mirror of https://github.com/JorjBauer/aiie.git
Compare commits
46 Commits
2fd5c6c79b
...
26a0a2abd5
Author | SHA1 | Date |
---|---|---|
Jorj Bauer | 26a0a2abd5 | |
Jorj Bauer | 70e28fa438 | |
Jorj Bauer | 97072d7dd6 | |
Jorj Bauer | 207399b07b | |
Jorj Bauer | 0473196d40 | |
Jorj Bauer | 1c09349746 | |
Jorj Bauer | 0a47ec63f5 | |
Jorj Bauer | 764a18d598 | |
Jorj Bauer | 413c81bed3 | |
Jorj Bauer | 1b43f1182e | |
Jorj Bauer | 16d84320ba | |
Jorj Bauer | 31e380526c | |
Jorj Bauer | ec691374ea | |
Jorj Bauer | 8cd2bc24ab | |
Jorj Bauer | 3e2ddb725f | |
Jorj Bauer | 274c93fd13 | |
Jorj Bauer | 900e242adc | |
Jorj Bauer | 0a2fb1aeee | |
Jorj Bauer | 0f4e4be73c | |
Jorj Bauer | 6d473cff0e | |
Jorj Bauer | 5cb631057c | |
Jorj Bauer | ab888aea88 | |
Jorj Bauer | a7f6307174 | |
Jorj Bauer | 7464e05578 | |
Jorj Bauer | 7d4505c83f | |
Jorj Bauer | 4f266a7f4f | |
Jorj Bauer | 2a05d9d90f | |
Jorj Bauer | 44be04ff97 | |
Jorj Bauer | ee89426d6e | |
Jorj Bauer | c906df1093 | |
Jorj Bauer | dd76741c23 | |
Jorj Bauer | 4978485ca5 | |
Jorj Bauer | 18356b92fe | |
Jorj Bauer | fac84b53b0 | |
Jorj Bauer | 17752f0c12 | |
Jorj Bauer | eb60d86ab5 | |
Jorj Bauer | 6d41176ee6 | |
Jorj Bauer | e10a885a85 | |
Jorj Bauer | d23f0d1bd5 | |
Jorj Bauer | 1d2fb10e0f | |
Jorj Bauer | d7b833da61 | |
Jorj Bauer | f1c8b7ba04 | |
Jorj Bauer | 69ee74079c | |
Jorj Bauer | 12a84422c9 | |
Jorj Bauer | a3db2e5c20 | |
Jorj Bauer | 31d200ac68 |
4
Makefile
4
Makefile
|
@ -8,9 +8,9 @@ CXXFLAGS=-Wall -I/usr/include/SDL2 -I .. -I . -I apple -I nix -I sdl -I/usr/loca
|
|||
|
||||
TSRC=cpu.cpp util/testharness.cpp
|
||||
|
||||
COMMONSRCS=cpu.cpp apple/appledisplay.cpp apple/applekeyboard.cpp apple/applemmu.cpp apple/applevm.cpp apple/diskii.cpp apple/nibutil.cpp LRingBuffer.cpp globals.cpp apple/parallelcard.cpp apple/fx80.cpp lcg.cpp apple/hd32.cpp images.cpp apple/appleui.cpp vmram.cpp bios.cpp apple/noslotclock.cpp apple/woz.cpp apple/crc32.c apple/woz-serializer.cpp apple/mouse.c
|
||||
COMMONSRCS=cpu.cpp apple/appledisplay.cpp apple/applekeyboard.cpp apple/applemmu.cpp apple/applevm.cpp apple/diskii.cpp apple/nibutil.cpp LRingBuffer.cpp globals.cpp apple/parallelcard.cpp apple/fx80.cpp lcg.cpp apple/hd32.cpp images.cpp apple/appleui.cpp vmram.cpp bios.cpp apple/noslotclock.cpp apple/woz.cpp apple/crc32.c apple/woz-serializer.cpp apple/mouse.c physicaldisplay.cpp
|
||||
|
||||
COMMONOBJS=cpu.o apple/appledisplay.o apple/applekeyboard.o apple/applemmu.o apple/applevm.o apple/diskii.o apple/nibutil.o LRingBuffer.o globals.o apple/parallelcard.o apple/fx80.o lcg.o apple/hd32.o images.o apple/appleui.o vmram.o bios.o apple/noslotclock.o apple/woz.o apple/crc32.o apple/woz-serializer.o apple/mouse.o
|
||||
COMMONOBJS=cpu.o apple/appledisplay.o apple/applekeyboard.o apple/applemmu.o apple/applevm.o apple/diskii.o apple/nibutil.o LRingBuffer.o globals.o apple/parallelcard.o apple/fx80.o lcg.o apple/hd32.o images.o apple/appleui.o vmram.o bios.o apple/noslotclock.o apple/woz.o apple/crc32.o apple/woz-serializer.o apple/mouse.o physicaldisplay.o
|
||||
|
||||
FBSRCS=linuxfb/linux-speaker.cpp linuxfb/fb-display.cpp linuxfb/linux-keyboard.cpp linuxfb/fb-paddles.cpp nix/nix-filemanager.cpp linuxfb/aiie.cpp linuxfb/linux-printer.cpp nix/nix-clock.cpp nix/nix-prefs.cpp
|
||||
|
||||
|
|
|
@ -85,10 +85,9 @@ You'll also need the ILI9341_t3n library from
|
|||
|
||||
https://github.com/KurtE/ILI9341_t3n/
|
||||
|
||||
I'm using it at tag f1bfb81825c60e39e011e502fe5c39a04305e1dc - not
|
||||
because that tag is special, but because that's when I checked out the
|
||||
repo. I haven't tested newer code and if you have problems, you'll
|
||||
want to roll back to that tag.
|
||||
As of this writing, the master branch does not work for Aiie; but the
|
||||
branch "dma_new_fix" is fine. I'd recommend checking out that branch
|
||||
if it exists.
|
||||
|
||||
# Running (on the Teensy)
|
||||
|
||||
|
|
|
@ -42,8 +42,6 @@
|
|||
|
||||
#define drawApplePixel(c,x,y) { g_display->cacheDoubleWidePixel(x,y,c); }
|
||||
|
||||
#define draw2Pixels(cA, cB, x, y) { g_display->cache2DoubleWidePixels(x,y,cA, cB); }
|
||||
|
||||
#define DrawLoresPixelAt(c, x, y) { \
|
||||
uint8_t pixel = c & 0x0F; \
|
||||
for (uint8_t y2 = 0; y2<4; y2++) { \
|
||||
|
@ -408,7 +406,7 @@ void AppleDisplay::redraw80ColumnText(uint8_t startingY)
|
|||
cptr = xlateChar(mmu->readDirect(addr, 1), &invert);
|
||||
for (uint8_t y2 = 0; y2<8; y2++) {
|
||||
uint8_t d = *(cptr + y2);
|
||||
for (uint8_t x2 = 0; x2 <= 7; x2++) {
|
||||
for (uint8_t x2 = 0; x2 < 7; x2++) {
|
||||
uint16_t basex = (col*2)*7;
|
||||
bool pixelOn = (d & (1<<x2));
|
||||
if (pixelOn) {
|
||||
|
@ -425,7 +423,7 @@ void AppleDisplay::redraw80ColumnText(uint8_t startingY)
|
|||
cptr = xlateChar(mmu->readDirect(addr, 0), &invert);
|
||||
for (uint8_t y2 = 0; y2<8; y2++) {
|
||||
uint8_t d = *(cptr + y2);
|
||||
for (uint8_t x2 = 0; x2 <= 7; x2++) {
|
||||
for (uint8_t x2 = 0; x2 < 7; x2++) {
|
||||
uint16_t basex = (col*2+1)*7;
|
||||
bool pixelOn = (d & (1<<x2));
|
||||
if (pixelOn) {
|
||||
|
@ -462,7 +460,6 @@ void AppleDisplay::redraw40ColumnText(uint8_t startingY)
|
|||
// Only draw onscreen locations
|
||||
if (row >= startingY && col <= 39 && row <= 23) {
|
||||
const uint8_t *cptr = xlateChar(mmu->readDirect(addr, 0), &invert);
|
||||
|
||||
for (uint8_t y2 = 0; y2<8; y2++) {
|
||||
uint8_t d = *(cptr + y2);
|
||||
for (uint8_t x2 = 0; x2 < 7; x2++) {
|
||||
|
@ -488,7 +485,8 @@ void AppleDisplay::redrawHires()
|
|||
start = 0x2000;
|
||||
}
|
||||
|
||||
// FIXME: check MIXED & don't redraw the lower area if it's set
|
||||
// S_MIXED is checked inside Draw14HiresPixelsAt and
|
||||
// Draw14DoubleHiresPixelsAt, so no need to check it here
|
||||
for (uint16_t addr = start; addr <= start + 0x1FFF; addr+=2) {
|
||||
if ((*switches) & S_DHIRES) {
|
||||
// FIXME: inline & optimize
|
||||
|
@ -502,15 +500,17 @@ void AppleDisplay::redrawHires()
|
|||
|
||||
void AppleDisplay::redrawLores()
|
||||
{
|
||||
// FIXME: can make more efficient by checking S_MIXED for lower bound
|
||||
|
||||
if (((*switches) & S_80COL) && ((*switches) & S_DHIRES)) {
|
||||
for (uint16_t addr = 0x400; addr <= 0x400 + 0x3ff; addr++) {
|
||||
uint8_t row, col;
|
||||
deinterlaceAddress(addr, &row, &col);
|
||||
if (col <= 39 && row <= 23) {
|
||||
Draw80LoresPixelAt(mmu->readDirect(addr, 0), col, row, 1);
|
||||
Draw80LoresPixelAt(mmu->readDirect(addr, 1), col, row, 0);
|
||||
if (((*switches) & S_MIXED) && row >= 20) { // ***@@@ is 20 right?
|
||||
// Don't draw this row, we're in MIXED mode
|
||||
} else {
|
||||
Draw80LoresPixelAt(mmu->readDirect(addr, 0), col, row, 1);
|
||||
Draw80LoresPixelAt(mmu->readDirect(addr, 1), col, row, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -518,8 +518,12 @@ void AppleDisplay::redrawLores()
|
|||
for (uint16_t addr = start; addr <= start + 0x3FF; addr++) {
|
||||
uint8_t row, col;
|
||||
deinterlaceAddress(addr, &row, &col);
|
||||
if (col <= 39 && row <= 23) {
|
||||
DrawLoresPixelAt(mmu->readDirect(addr, 0), col, row);
|
||||
if (((*switches) & S_MIXED) && row >= 20) { // ***@@@ is 20 right?
|
||||
// Don't draw this row, we're in MIXED mode
|
||||
} else {
|
||||
if (col <= 39 && row <= 23) {
|
||||
DrawLoresPixelAt(mmu->readDirect(addr, 0), col, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -547,17 +551,25 @@ void AppleDisplay::Draw80LoresPixelAt(uint8_t c, uint8_t x, uint8_t y, uint8_t o
|
|||
// The colors in every other column are swizzled. Un-swizzle.
|
||||
c = ((c & 0x77) << 1) | ((c & 0x88) >> 3);
|
||||
}
|
||||
|
||||
uint8_t pixel = c & 0x0F;
|
||||
for (uint8_t y2 = 0; y2<4; y2++) {
|
||||
for (int8_t x2 = 3; x2>=offset; x2--) {
|
||||
drawApplePixel(pixel, x*7+x2+offset*3, y*8+y2);
|
||||
|
||||
if ( !(*switches & S_MIXED) ||
|
||||
y < 20 ) {
|
||||
drawApplePixel(pixel, x*7+x2+offset*3, y*8+y2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pixel = (c >> 4);
|
||||
for (uint8_t y2 = 4; y2<8; y2++) {
|
||||
for (int8_t x2 = 3; x2>=offset; x2--) {
|
||||
drawApplePixel(pixel, x*7+x2+offset*3, y*8+y2);
|
||||
if ( !(*switches & S_MIXED) ||
|
||||
y < 20 ) {
|
||||
drawApplePixel(pixel, x*7+x2+offset*3, y*8+y2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -470,7 +470,7 @@ uint8_t AppleMMU::readSwitches(uint16_t address)
|
|||
return slots[i]->readSwitches(address & ~(0xC080 | (i<<4)));
|
||||
}
|
||||
else
|
||||
return FLOATING;
|
||||
return _FLOATINGBUS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -505,7 +505,7 @@ uint8_t AppleMMU::readSwitches(uint16_t address)
|
|||
// by even read access
|
||||
preWriteFlag = (address & 0x01);
|
||||
|
||||
return FLOATING;
|
||||
return _FLOATINGBUS;
|
||||
|
||||
case 0xC00C: // CLR80VID disable 80-col video mode
|
||||
if (switches & S_80COL) {
|
||||
|
@ -575,32 +575,32 @@ uint8_t AppleMMU::readSwitches(uint16_t address)
|
|||
// loop b/c the speaker might need attention
|
||||
// immediately
|
||||
#endif
|
||||
return FLOATING;
|
||||
return _FLOATINGBUS;
|
||||
|
||||
case 0xC050: // CLRTEXT
|
||||
if (switches & S_TEXT) {
|
||||
switches &= ~S_TEXT;
|
||||
resetDisplay();
|
||||
}
|
||||
return FLOATING;
|
||||
return _FLOATINGBUS;
|
||||
case 0xC051: // SETTEXT
|
||||
if (!(switches & S_TEXT)) {
|
||||
switches |= S_TEXT;
|
||||
resetDisplay();
|
||||
}
|
||||
return FLOATING;
|
||||
return _FLOATINGBUS;
|
||||
case 0xC052: // CLRMIXED
|
||||
if (switches & S_MIXED) {
|
||||
switches &= ~S_MIXED;
|
||||
resetDisplay();
|
||||
}
|
||||
return FLOATING;
|
||||
return _FLOATINGBUS;
|
||||
case 0xC053: // SETMIXED
|
||||
if (!(switches & S_MIXED)) {
|
||||
switches |= S_MIXED;
|
||||
resetDisplay();
|
||||
}
|
||||
return FLOATING;
|
||||
return _FLOATINGBUS;
|
||||
|
||||
case 0xC054: // PAGE1
|
||||
if (switches & S_PAGE2) {
|
||||
|
@ -611,7 +611,7 @@ uint8_t AppleMMU::readSwitches(uint16_t address)
|
|||
updateMemoryPages();
|
||||
}
|
||||
}
|
||||
return FLOATING;
|
||||
return _FLOATINGBUS;
|
||||
|
||||
case 0xC055: // PAGE2
|
||||
if (!(switches & S_PAGE2)) {
|
||||
|
@ -622,34 +622,34 @@ uint8_t AppleMMU::readSwitches(uint16_t address)
|
|||
updateMemoryPages();
|
||||
}
|
||||
}
|
||||
return FLOATING;
|
||||
return _FLOATINGBUS;
|
||||
|
||||
case 0xC056: // CLRHIRES
|
||||
if (switches & S_HIRES) {
|
||||
switches &= ~S_HIRES;
|
||||
resetDisplay();
|
||||
}
|
||||
return FLOATING;
|
||||
return _FLOATINGBUS;
|
||||
case 0xC057: // SETHIRES
|
||||
if (!(switches & S_HIRES)) {
|
||||
switches |= S_HIRES;
|
||||
resetDisplay();
|
||||
}
|
||||
return FLOATING;
|
||||
return _FLOATINGBUS;
|
||||
|
||||
case 0xC05E: // DHIRES ON
|
||||
if (!(switches & S_DHIRES)) {
|
||||
switches |= S_DHIRES;
|
||||
resetDisplay();
|
||||
}
|
||||
return FLOATING;
|
||||
return _FLOATINGBUS;
|
||||
|
||||
case 0xC05F: // DHIRES OFF
|
||||
if (switches & S_DHIRES) {
|
||||
switches &= ~S_DHIRES;
|
||||
resetDisplay();
|
||||
}
|
||||
return FLOATING;
|
||||
return _FLOATINGBUS;
|
||||
|
||||
// paddles
|
||||
/* Fall through for apple keys; they're just RAM in this model
|
||||
|
@ -665,7 +665,7 @@ uint8_t AppleMMU::readSwitches(uint16_t address)
|
|||
g_ram.writeByte((writePages[0xC0] << 8) | 0x64, 0xFF);
|
||||
g_ram.writeByte((writePages[0xC0] << 8) | 0x65, 0xFF);
|
||||
g_paddles->startReading();
|
||||
return FLOATING;
|
||||
return _FLOATINGBUS;
|
||||
}
|
||||
|
||||
if (address >= 0xc000 && address <= 0xc00f) {
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
#include "mmu.h"
|
||||
#include "noslotclock.h"
|
||||
|
||||
// when we read a nondeterministic result, we return FLOATING. Maybe
|
||||
// some day we can come back here and figure out how to return what
|
||||
// the Apple would have.
|
||||
// when we read a nondeterministic result, we return
|
||||
// _FLOATINGBUS. Maybe some day we can come back here and figure out
|
||||
// how to return what the Apple would have.
|
||||
|
||||
#define FLOATING 0
|
||||
#define _FLOATINGBUS 0
|
||||
|
||||
// Switches activated by various memory locations
|
||||
enum {
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
#include "appleui.h"
|
||||
|
||||
#include "vm.h" // for DISPLAYHEIGHT. Probably not the most sensible.
|
||||
#include "images.h"
|
||||
#include "vm.h"
|
||||
#include "images.h" // for the image abstraction constants
|
||||
#include "globals.h"
|
||||
|
||||
// FIXME: abstract and standardize the sizes, onscreen locations, and
|
||||
// underlying bitmap types
|
||||
|
||||
AppleUI::AppleUI()
|
||||
{
|
||||
redrawFrame = false;
|
||||
redrawDriveLatches = false;
|
||||
redrawDriveActivity = false;
|
||||
redrawFrame = true;
|
||||
redrawDriveLatches = true;
|
||||
redrawDriveActivity = true;
|
||||
driveInserted[0] = driveInserted[1] = 0;
|
||||
driveActivity[0] = driveActivity[1] = 0;
|
||||
}
|
||||
|
@ -48,38 +45,48 @@ void AppleUI::drawPercentageUIElement(uint8_t element, uint8_t percent)
|
|||
if (element != UIePowerPercentage) {
|
||||
return;
|
||||
}
|
||||
// Temporarily disabled; the API for this needs updating for resolution-independent display coordinates
|
||||
// drawBatteryStatus(percent);
|
||||
drawBatteryStatus(percent);
|
||||
}
|
||||
|
||||
void AppleUI::drawBatteryStatus(uint8_t percent)
|
||||
{
|
||||
return; // *** FIXME: image and positioning not updated for new aspect ratio
|
||||
|
||||
uint16_t xoff = 301;
|
||||
uint16_t yoff = 222;
|
||||
|
||||
// the area around the apple is 12 wide; it's exactly 11 high the
|
||||
// color is 210/202/159
|
||||
|
||||
float watermark = ((float)percent / 100.0) * 11;
|
||||
static uint8_t *img = NULL;
|
||||
static uint16_t h,w;
|
||||
if (!img) {
|
||||
if (!getImageInfoAndData(IMG_APPLEBATTERY, &w, &h, &img)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
float watermark = ((float)percent / 100.0) * h;
|
||||
|
||||
for (int y=0; y<11; y++) {
|
||||
for (int y=0; y<h; y++) {
|
||||
uint8_t bgr = 210;
|
||||
uint8_t bgg = 202;
|
||||
uint8_t bgb = 159;
|
||||
|
||||
if (11-y > watermark) {
|
||||
if ((h-y) > watermark) {
|
||||
// black...
|
||||
bgr = bgg = bgb = 0;
|
||||
}
|
||||
|
||||
for (int x=0; x<10; x++) {
|
||||
uint16_t w = w;
|
||||
for (int x=0; x<w; x++) {
|
||||
#ifdef TEENSYDUINO
|
||||
uint8_t r = pgm_read_byte(&appleBitmap[(y * 10 + x)*4 + 0]);
|
||||
uint8_t g = pgm_read_byte(&appleBitmap[(y * 10 + x)*4 + 1]);
|
||||
uint8_t b = pgm_read_byte(&appleBitmap[(y * 10 + x)*4 + 2]);
|
||||
uint8_t a = pgm_read_byte(&appleBitmap[(y * 10 + x)*4 + 3]);
|
||||
uint8_t r = pgm_read_byte(&img[(y * w + x)*4 + 0]);
|
||||
uint8_t g = pgm_read_byte(&img[(y * w + x)*4 + 1]);
|
||||
uint8_t b = pgm_read_byte(&img[(y * w + x)*4 + 2]);
|
||||
uint8_t a = pgm_read_byte(&img[(y * w + x)*4 + 3]);
|
||||
#else
|
||||
const uint8_t *p = &appleBitmap[(y * 10 + (x-1))*4];
|
||||
const uint8_t *p = &img[(y * w + (x-1))*4];
|
||||
uint8_t r, g, b, a;
|
||||
r = p[0];
|
||||
g = p[1];
|
||||
|
@ -94,7 +101,7 @@ void AppleUI::drawBatteryStatus(uint8_t percent)
|
|||
b = (float)b * alpha + (bgb * (1.0 - alpha));
|
||||
|
||||
uint16_t color16 = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3);
|
||||
g_display->drawUIPixel(x+xoff, y+yoff, color16);
|
||||
g_display->drawPixel(x+xoff, y+yoff, color16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,40 +110,19 @@ void AppleUI::blit()
|
|||
{
|
||||
if (redrawFrame) {
|
||||
redrawFrame = false;
|
||||
g_display->drawImageOfSizeAt(displayBitmap, DBITMAP_WIDTH, DBITMAP_HEIGHT, 0, 0);
|
||||
g_display->drawUIImage(IMG_SHELL);
|
||||
}
|
||||
|
||||
if (redrawDriveLatches) {
|
||||
redrawDriveLatches = false;
|
||||
uint16_t xoff = 55;
|
||||
uint8_t yoff = 216;
|
||||
uint16_t xsize;
|
||||
uint8_t ysize;
|
||||
const uint8_t *img;
|
||||
|
||||
xsize = 43;
|
||||
ysize = 20;
|
||||
img = driveInserted[0] ? driveLatchOpen : driveLatch;
|
||||
g_display->drawImageOfSizeAt(img, xsize, ysize, xoff, yoff);
|
||||
|
||||
xoff += 134;
|
||||
img = driveInserted[1] ? driveLatchOpen : driveLatch;
|
||||
g_display->drawImageOfSizeAt(img, xsize, ysize, xoff, yoff);
|
||||
g_display->drawUIImage(driveInserted[0] ? IMG_D1CLOSED : IMG_D1OPEN);
|
||||
g_display->drawUIImage(driveInserted[1] ? IMG_D2CLOSED : IMG_D2OPEN);
|
||||
redrawDriveActivity = true; // these overlap
|
||||
}
|
||||
|
||||
if (redrawDriveActivity) {
|
||||
redrawDriveActivity = false;
|
||||
|
||||
uint16_t xoff = 125;
|
||||
uint8_t yoff = 213;
|
||||
|
||||
for (int x=0; x<6; x++) {
|
||||
g_display->drawUIPixel(x + xoff, yoff, driveActivity[0] ? 0xFA00 : 0x0000);
|
||||
g_display->drawUIPixel(x + xoff, yoff + 1, driveActivity[0] ? 0xFA00 : 0x0000);
|
||||
|
||||
g_display->drawUIPixel(x + xoff + 135, yoff, driveActivity[1] ? 0xFA00 : 0x0000);
|
||||
g_display->drawUIPixel(x + xoff + 135, yoff + 1, driveActivity[1] ? 0xFA00 : 0x0000);
|
||||
}
|
||||
g_display->drawDriveActivity(driveActivity[0], driveActivity[1]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#include "applemmu.h" // for FLOATING
|
||||
#include "applemmu.h" // for _FLOATINGBUS
|
||||
|
||||
#include "globals.h"
|
||||
#include "appleui.h"
|
||||
|
@ -273,7 +273,7 @@ uint8_t DiskII::readSwitches(uint8_t s)
|
|||
|
||||
// Any even address read returns the readWriteLatch (UTA2E Table 9.1,
|
||||
// p. 9-12, note 2)
|
||||
return (s & 1) ? FLOATING : readWriteLatch;
|
||||
return (s & 1) ? _FLOATINGBUS : readWriteLatch;
|
||||
}
|
||||
|
||||
void DiskII::writeSwitches(uint8_t s, uint8_t v)
|
||||
|
|
|
@ -22,8 +22,6 @@
|
|||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "applemmu.h" // for FLOATING
|
||||
|
||||
#include "serialize.h"
|
||||
|
||||
#include "globals.h"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "noslotclock.h"
|
||||
#include "applemmu.h" // for FLOATING
|
||||
|
||||
#define initSequence 0x5CA33AC55CA33AC5LL
|
||||
|
||||
|
|
36
bios.cpp
36
bios.cpp
|
@ -137,12 +137,12 @@ void BIOS::DrawMenuBar()
|
|||
|
||||
for (int i=0; i<NUM_TITLES; i++) {
|
||||
for (int x=0; x<titleWidths[i] + 2*XPADDING; x++) {
|
||||
g_display->drawUIPixel(xpos+x, 0, 0xFFFF);
|
||||
g_display->drawUIPixel(xpos+x, LINEHEIGHT, 0xFFFF);
|
||||
g_display->drawPixel(xpos+x, 0, 0xFFFF);
|
||||
g_display->drawPixel(xpos+x, LINEHEIGHT, 0xFFFF);
|
||||
}
|
||||
for (int y=0; y<=LINEHEIGHT; y++) {
|
||||
g_display->drawUIPixel(xpos, y, 0xFFFF);
|
||||
g_display->drawUIPixel(xpos + titleWidths[i] + 2*XPADDING, y, 0xFFFF);
|
||||
g_display->drawPixel(xpos, y, 0xFFFF);
|
||||
g_display->drawPixel(xpos + titleWidths[i] + 2*XPADDING, y, 0xFFFF);
|
||||
}
|
||||
|
||||
xpos += XPADDING;
|
||||
|
@ -244,7 +244,7 @@ bool BIOS::loop()
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch (selectedMenu) {
|
||||
case BIOS_AIIE:
|
||||
rv = AiieMenuHandler(needsRedraw, hitReturn);
|
||||
|
@ -551,7 +551,7 @@ uint16_t BIOS::AboutScreenHandler(bool needsRedraw, bool performAction)
|
|||
// Draw a black area where we're going to "boot" a fake //e for the about screen. Don't put the whole graphic around it so it's obvious it's not a //e.
|
||||
for (uint8_t y=12; y<12+192; y++) {
|
||||
for (uint16_t x=20; x<280+20; x++) {
|
||||
g_display->drawUIPixel( x, y, 0x0000 );
|
||||
g_display->drawPixel( x, y, 0x0000 );
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
@ -682,26 +682,26 @@ uint16_t BIOS::PaddlesScreenHandler(bool needsRedraw, bool performAction)
|
|||
// Draw the target for the paddle position
|
||||
for (uint16_t y=10; y<=110; y++) {
|
||||
for (uint16_t x=160; x<=260; x++) {
|
||||
g_display->drawUIPixel(x, y, 0x0000);
|
||||
g_display->drawUIPixel(x, 10, 0xFFFF);
|
||||
g_display->drawUIPixel(x, 110, 0xFFFF);
|
||||
g_display->drawPixel(x, y, 0x0000);
|
||||
g_display->drawPixel(x, 10, 0xFFFF);
|
||||
g_display->drawPixel(x, 110, 0xFFFF);
|
||||
}
|
||||
g_display->drawUIPixel(160, y, 0xFFFF);
|
||||
g_display->drawUIPixel(260, y, 0xFFFF);
|
||||
g_display->drawPixel(160, y, 0xFFFF);
|
||||
g_display->drawPixel(260, y, 0xFFFF);
|
||||
}
|
||||
|
||||
for (uint16_t y=57; y<=63; y++) {
|
||||
g_display->drawUIPixel(207,y,0xFFFF);
|
||||
g_display->drawUIPixel(213,y,0xFFFF);
|
||||
g_display->drawPixel(207,y,0xFFFF);
|
||||
g_display->drawPixel(213,y,0xFFFF);
|
||||
}
|
||||
for (uint16_t x=207; x<=213; x++) {
|
||||
g_display->drawUIPixel(x,57,0xFFFF);
|
||||
g_display->drawUIPixel(x,63,0xFFFF);
|
||||
g_display->drawPixel(x,57,0xFFFF);
|
||||
g_display->drawPixel(x,63,0xFFFF);
|
||||
}
|
||||
|
||||
float drawX = ((float)lastPaddleX/255.0)*100.0;
|
||||
float drawY = ((float)lastPaddleY/255.0)*100.0;
|
||||
g_display->drawUIPixel(160+drawX, 10+drawY, 0xFFFF);
|
||||
g_display->drawPixel(160+drawX, 10+drawY, 0xFFFF);
|
||||
|
||||
g_display->flush();
|
||||
|
||||
|
@ -1050,7 +1050,7 @@ void BIOS::DrawHardwareMenu()
|
|||
uint16_t volCutoff = 300.0 * (float)((float) g_volume / 15.0);
|
||||
for (uint8_t y=234; y<=235; y++) {
|
||||
for (uint16_t x = 0; x< 300; x++) {
|
||||
g_display->drawUIPixel( x, y, x <= volCutoff ? 0xFFFF : 0x0010 );
|
||||
g_display->drawPixel( x, y, x <= volCutoff ? 0xFFFF : 0x0010 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1159,7 +1159,7 @@ uint16_t BIOS::DrawDiskNames(uint8_t page, int8_t selection, const char *filter)
|
|||
g_display->drawString(M_NORMAL, 0, 0, title);
|
||||
|
||||
for (int x=0; x<strlen(title)*8; x++) {
|
||||
g_display->drawUIPixel(x, LINEHEIGHT-1, 0xFFFF);
|
||||
g_display->drawPixel(x, LINEHEIGHT-1, 0xFFFF);
|
||||
}
|
||||
|
||||
uint8_t vpos = FILEMENUSTARTAT;
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
const static uint8_t image_8875_apple[] PROGMEM = {
|
||||
0xA7, 0xD7, 0x98, 0x00, 0x87, 0xCC, 0x72, 0x00,
|
||||
0x7B, 0xC1, 0x65, 0x00, 0x9D, 0xD0, 0x8D, 0x00,
|
||||
0xBF, 0xE0, 0xB7, 0x00, 0x81, 0xC9, 0x6A, 0x6F,
|
||||
0x68, 0xC0, 0x4B, 0xC0, 0x95, 0xCF, 0x83, 0x05,
|
||||
0x96, 0xCE, 0x84, 0x00, 0x95, 0xCE, 0x83, 0x00,
|
||||
0xA7, 0xD6, 0x98, 0x00, 0x88, 0xCC, 0x73, 0x00,
|
||||
0x7E, 0xC2, 0x69, 0x00, 0x8E, 0xCA, 0x7B, 0x00,
|
||||
0x96, 0xD0, 0x84, 0x42, 0x59, 0xBB, 0x38, 0xFF,
|
||||
0x7D, 0xC6, 0x65, 0x81, 0x95, 0xCE, 0x84, 0x00,
|
||||
0x8C, 0xCD, 0x77, 0x00, 0xCC, 0xE7, 0xC3, 0x00,
|
||||
0xA6, 0xD8, 0x9D, 0x00, 0x7F, 0xCB, 0x6E, 0x1C,
|
||||
0x6D, 0xC0, 0x59, 0x67, 0x73, 0xC3, 0x5F, 0x4E,
|
||||
0x7A, 0xC8, 0x68, 0x70, 0x66, 0xC2, 0x4F, 0xA1,
|
||||
0x73, 0xC3, 0x60, 0x61, 0x70, 0xC2, 0x5D, 0x60,
|
||||
0x80, 0xCB, 0x6D, 0x15, 0xDB, 0xEF, 0xD5, 0x00,
|
||||
0xA7, 0xD1, 0x81, 0x32, 0x72, 0xBD, 0x3A, 0xE7,
|
||||
0x6D, 0xBC, 0x34, 0xFF, 0x6E, 0xBC, 0x35, 0xFF,
|
||||
0x73, 0xBE, 0x3C, 0xED, 0x72, 0xBD, 0x3B, 0xE6,
|
||||
0x6D, 0xBC, 0x35, 0xFF, 0x6C, 0xBB, 0x31, 0xFF,
|
||||
0x70, 0xBF, 0x3F, 0xCF, 0xD5, 0xEE, 0xD4, 0x0C,
|
||||
0xF5, 0xC0, 0x19, 0xB9, 0xF7, 0xBB, 0x00, 0xFF,
|
||||
0xF7, 0xBC, 0x03, 0xFF, 0xF7, 0xBC, 0x03, 0xFF,
|
||||
0xF7, 0xBC, 0x02, 0xFF, 0xF7, 0xBC, 0x02, 0xFF,
|
||||
0xF7, 0xBC, 0x03, 0xFF, 0xF9, 0xBB, 0x00, 0xFF,
|
||||
0xE4, 0xC6, 0x42, 0x67, 0xE2, 0xE8, 0xBF, 0x00,
|
||||
0xFC, 0x99, 0x02, 0xE9, 0xFD, 0x99, 0x00, 0xFF,
|
||||
0xFD, 0x99, 0x00, 0xFF, 0xFD, 0x99, 0x00, 0xFF,
|
||||
0xFD, 0x99, 0x00, 0xFF, 0xFD, 0x99, 0x00, 0xFF,
|
||||
0xFD, 0x98, 0x00, 0xFF, 0xFD, 0x9D, 0x09, 0xE9,
|
||||
0xFB, 0xB6, 0x5A, 0x11, 0xF9, 0xB5, 0x5C, 0x00,
|
||||
0xF2, 0x6D, 0x10, 0xE6, 0xF2, 0x6B, 0x0E, 0xFF,
|
||||
0xF2, 0x6B, 0x0E, 0xFF, 0xF2, 0x6B, 0x0E, 0xFF,
|
||||
0xF2, 0x6B, 0x0E, 0xFF, 0xF2, 0x6B, 0x0E, 0xFF,
|
||||
0xF2, 0x6A, 0x0D, 0xFF, 0xF2, 0x6D, 0x13, 0xF4,
|
||||
0xF0, 0x8E, 0x53, 0x23, 0xF5, 0xB8, 0x92, 0x00,
|
||||
0xE1, 0x46, 0x4D, 0xBD, 0xE0, 0x32, 0x39, 0xFF,
|
||||
0xE0, 0x35, 0x3C, 0xFF, 0xE0, 0x35, 0x3C, 0xFF,
|
||||
0xE0, 0x35, 0x3C, 0xFF, 0xE0, 0x35, 0x3C, 0xFF,
|
||||
0xE0, 0x35, 0x3C, 0xFF, 0xE0, 0x33, 0x3A, 0xFF,
|
||||
0xE0, 0x3F, 0x45, 0xAF, 0xEF, 0xA6, 0xAA, 0x15,
|
||||
0xBE, 0x67, 0x9F, 0x64, 0xA9, 0x2F, 0x83, 0xFF,
|
||||
0xAD, 0x32, 0x85, 0xFF, 0xAD, 0x32, 0x85, 0xFF,
|
||||
0xAD, 0x32, 0x85, 0xFF, 0xAD, 0x32, 0x85, 0xFF,
|
||||
0xAD, 0x32, 0x85, 0xFF, 0xAD, 0x32, 0x85, 0xFF,
|
||||
0xA6, 0x29, 0x7E, 0xFF, 0xCF, 0x8D, 0xBA, 0x52,
|
||||
0x8E, 0x9F, 0xD2, 0x06, 0x5F, 0x71, 0xC0, 0xC4,
|
||||
0x48, 0x66, 0xBC, 0xFF, 0x4C, 0x68, 0xBD, 0xFF,
|
||||
0x49, 0x67, 0xBD, 0xFF, 0x49, 0x67, 0xBD, 0xFF,
|
||||
0x4B, 0x68, 0xBD, 0xFF, 0x46, 0x65, 0xBC, 0xFF,
|
||||
0x68, 0x77, 0xC2, 0xAE, 0x97, 0xA5, 0xD3, 0x00,
|
||||
0x62, 0xC7, 0xEE, 0x00, 0x42, 0xC0, 0xEC, 0x23,
|
||||
0x01, 0xA6, 0xE4, 0xC8, 0x01, 0xA4, 0xE4, 0xDB,
|
||||
0x12, 0xAA, 0xE3, 0x90, 0x11, 0xAA, 0xE3, 0x93,
|
||||
0x00, 0xA4, 0xE4, 0xE0, 0x06, 0xA8, 0xE5, 0xBA,
|
||||
0x5C, 0xC8, 0xEC, 0x15, 0x77, 0xCC, 0xEC, 0x00
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,356 @@
|
|||
const static uint8_t image_d1_closed[] PROGMEM = {
|
||||
0xCE,0x37, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0xCD,0xF5, 0x20,0xC1, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x20,0xC1, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x29,0x43,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x29,0x43, 0x29,0x43, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x29,0x43, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x29,0x43, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x29,0x43,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x29,0x43, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0xCE,0x37, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0xCD,0xD5,
|
||||
};
|
||||
|
||||
const static uint8_t image_d1_open[] PROGMEM = {
|
||||
0xCE,0x37, 0x31,0x23, 0x10,0x81, 0x18,0x81, 0x20,0xC1, 0x29,0x02, 0x28,0xE2, 0x28,0xC2,
|
||||
0x31,0x01, 0x29,0x01, 0x20,0xC1, 0x28,0xE1, 0x31,0x42, 0x28,0xC1, 0x20,0xA0, 0x31,0x22,
|
||||
0x31,0x01, 0x28,0xE1, 0x31,0x02, 0x30,0xE1, 0x20,0xA0, 0x20,0xA0, 0x20,0xA0, 0x28,0xC1,
|
||||
0x31,0x02, 0x28,0xE1, 0x28,0xE1, 0x28,0xE2, 0x20,0xA1, 0x28,0xE2, 0x28,0xE1, 0x20,0xA1,
|
||||
0x29,0x02, 0x29,0x01, 0x20,0xC0, 0x20,0xC1, 0x28,0xE1, 0x31,0x22, 0x29,0x02, 0x31,0x22,
|
||||
0x29,0x01, 0x28,0xE1, 0x31,0x01, 0x30,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0xCD,0xF5, 0x52,0x66, 0x41,0xE6,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x20,0xC1, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x29,0x43,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x29,0x43, 0x29,0x43, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x29,0x43, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x29,0x43, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x29,0x43,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x29,0x43, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0xCE,0x37, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0xCD,0xD5,
|
||||
};
|
||||
|
||||
const static uint8_t image_d2_closed[] PROGMEM = {
|
||||
0xCE,0x37, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0xCD,0xF5, 0x20,0xC1, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x20,0xC1, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x52,0x68, 0x41,0xC5, 0x4A,0x27,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x5A,0xA9, 0x52,0x27, 0x6B,0x4B, 0x52,0x68, 0x52,0x47, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x41,0xC5, 0x62,0xC9, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x41,0xC5, 0x4A,0x47, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x39,0xA5, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x4A,0x27, 0x39,0xA4, 0x39,0xC5, 0x42,0x06, 0x62,0xE9, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0xCE,0x37, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B, 0x6B,0x4B,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0xCD,0xD5,
|
||||
};
|
||||
|
||||
const static uint8_t image_d2_open[] PROGMEM = {
|
||||
0xCE,0x37, 0x31,0x23, 0x10,0x81, 0x18,0x81, 0x20,0xC1, 0x29,0x02, 0x28,0xE2, 0x28,0xC2,
|
||||
0x31,0x01, 0x29,0x01, 0x20,0xC1, 0x28,0xE1, 0x31,0x42, 0x28,0xC1, 0x20,0xA0, 0x31,0x22,
|
||||
0x31,0x01, 0x28,0xE1, 0x31,0x02, 0x30,0xE1, 0x20,0xA0, 0x20,0xA0, 0x20,0xA0, 0x28,0xC1,
|
||||
0x31,0x02, 0x28,0xE1, 0x28,0xE1, 0x28,0xE2, 0x20,0xA1, 0x28,0xE2, 0x28,0xE1, 0x20,0xA1,
|
||||
0x29,0x02, 0x29,0x01, 0x20,0xC0, 0x20,0xC1, 0x28,0xE1, 0x31,0x22, 0x29,0x02, 0x31,0x22,
|
||||
0x29,0x01, 0x28,0xE1, 0x31,0x01, 0x30,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1,
|
||||
0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0x20,0xC1, 0xCD,0xF5, 0x52,0x66, 0x41,0xE6,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x20,0xC1, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x52,0x68, 0x41,0xC5, 0x4A,0x27,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x5A,0xA9, 0x52,0x27, 0x8C,0x6F, 0x52,0x68, 0x52,0x47, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x41,0xC5, 0x62,0xC9, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x41,0xC5, 0x4A,0x47, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x39,0xA5, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x4A,0x27, 0x39,0xA4, 0x39,0xC5, 0x42,0x06, 0x62,0xE9, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0xCE,0x37, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F, 0x8C,0x6F,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2, 0x58,0xA2,
|
||||
0x58,0xA2, 0xCD,0xD5,
|
||||
};
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
const uint8_t img_9341_applebitmap[] PROGMEM = {
|
||||
0xA7, 0xD7, 0x98, 0x00, 0x87, 0xCC, 0x72, 0x00,
|
||||
0x7B, 0xC1, 0x65, 0x00, 0x9D, 0xD0, 0x8D, 0x00,
|
||||
0xBF, 0xE0, 0xB7, 0x00, 0x81, 0xC9, 0x6A, 0x6F,
|
||||
0x68, 0xC0, 0x4B, 0xC0, 0x95, 0xCF, 0x83, 0x05,
|
||||
0x96, 0xCE, 0x84, 0x00, 0x95, 0xCE, 0x83, 0x00,
|
||||
0xA7, 0xD6, 0x98, 0x00, 0x88, 0xCC, 0x73, 0x00,
|
||||
0x7E, 0xC2, 0x69, 0x00, 0x8E, 0xCA, 0x7B, 0x00,
|
||||
0x96, 0xD0, 0x84, 0x42, 0x59, 0xBB, 0x38, 0xFF,
|
||||
0x7D, 0xC6, 0x65, 0x81, 0x95, 0xCE, 0x84, 0x00,
|
||||
0x8C, 0xCD, 0x77, 0x00, 0xCC, 0xE7, 0xC3, 0x00,
|
||||
0xA6, 0xD8, 0x9D, 0x00, 0x7F, 0xCB, 0x6E, 0x1C,
|
||||
0x6D, 0xC0, 0x59, 0x67, 0x73, 0xC3, 0x5F, 0x4E,
|
||||
0x7A, 0xC8, 0x68, 0x70, 0x66, 0xC2, 0x4F, 0xA1,
|
||||
0x73, 0xC3, 0x60, 0x61, 0x70, 0xC2, 0x5D, 0x60,
|
||||
0x80, 0xCB, 0x6D, 0x15, 0xDB, 0xEF, 0xD5, 0x00,
|
||||
0xA7, 0xD1, 0x81, 0x32, 0x72, 0xBD, 0x3A, 0xE7,
|
||||
0x6D, 0xBC, 0x34, 0xFF, 0x6E, 0xBC, 0x35, 0xFF,
|
||||
0x73, 0xBE, 0x3C, 0xED, 0x72, 0xBD, 0x3B, 0xE6,
|
||||
0x6D, 0xBC, 0x35, 0xFF, 0x6C, 0xBB, 0x31, 0xFF,
|
||||
0x70, 0xBF, 0x3F, 0xCF, 0xD5, 0xEE, 0xD4, 0x0C,
|
||||
0xF5, 0xC0, 0x19, 0xB9, 0xF7, 0xBB, 0x00, 0xFF,
|
||||
0xF7, 0xBC, 0x03, 0xFF, 0xF7, 0xBC, 0x03, 0xFF,
|
||||
0xF7, 0xBC, 0x02, 0xFF, 0xF7, 0xBC, 0x02, 0xFF,
|
||||
0xF7, 0xBC, 0x03, 0xFF, 0xF9, 0xBB, 0x00, 0xFF,
|
||||
0xE4, 0xC6, 0x42, 0x67, 0xE2, 0xE8, 0xBF, 0x00,
|
||||
0xFC, 0x99, 0x02, 0xE9, 0xFD, 0x99, 0x00, 0xFF,
|
||||
0xFD, 0x99, 0x00, 0xFF, 0xFD, 0x99, 0x00, 0xFF,
|
||||
0xFD, 0x99, 0x00, 0xFF, 0xFD, 0x99, 0x00, 0xFF,
|
||||
0xFD, 0x98, 0x00, 0xFF, 0xFD, 0x9D, 0x09, 0xE9,
|
||||
0xFB, 0xB6, 0x5A, 0x11, 0xF9, 0xB5, 0x5C, 0x00,
|
||||
0xF2, 0x6D, 0x10, 0xE6, 0xF2, 0x6B, 0x0E, 0xFF,
|
||||
0xF2, 0x6B, 0x0E, 0xFF, 0xF2, 0x6B, 0x0E, 0xFF,
|
||||
0xF2, 0x6B, 0x0E, 0xFF, 0xF2, 0x6B, 0x0E, 0xFF,
|
||||
0xF2, 0x6A, 0x0D, 0xFF, 0xF2, 0x6D, 0x13, 0xF4,
|
||||
0xF0, 0x8E, 0x53, 0x23, 0xF5, 0xB8, 0x92, 0x00,
|
||||
0xE1, 0x46, 0x4D, 0xBD, 0xE0, 0x32, 0x39, 0xFF,
|
||||
0xE0, 0x35, 0x3C, 0xFF, 0xE0, 0x35, 0x3C, 0xFF,
|
||||
0xE0, 0x35, 0x3C, 0xFF, 0xE0, 0x35, 0x3C, 0xFF,
|
||||
0xE0, 0x35, 0x3C, 0xFF, 0xE0, 0x33, 0x3A, 0xFF,
|
||||
0xE0, 0x3F, 0x45, 0xAF, 0xEF, 0xA6, 0xAA, 0x15,
|
||||
0xBE, 0x67, 0x9F, 0x64, 0xA9, 0x2F, 0x83, 0xFF,
|
||||
0xAD, 0x32, 0x85, 0xFF, 0xAD, 0x32, 0x85, 0xFF,
|
||||
0xAD, 0x32, 0x85, 0xFF, 0xAD, 0x32, 0x85, 0xFF,
|
||||
0xAD, 0x32, 0x85, 0xFF, 0xAD, 0x32, 0x85, 0xFF,
|
||||
0xA6, 0x29, 0x7E, 0xFF, 0xCF, 0x8D, 0xBA, 0x52,
|
||||
0x8E, 0x9F, 0xD2, 0x06, 0x5F, 0x71, 0xC0, 0xC4,
|
||||
0x48, 0x66, 0xBC, 0xFF, 0x4C, 0x68, 0xBD, 0xFF,
|
||||
0x49, 0x67, 0xBD, 0xFF, 0x49, 0x67, 0xBD, 0xFF,
|
||||
0x4B, 0x68, 0xBD, 0xFF, 0x46, 0x65, 0xBC, 0xFF,
|
||||
0x68, 0x77, 0xC2, 0xAE, 0x97, 0xA5, 0xD3, 0x00,
|
||||
0x62, 0xC7, 0xEE, 0x00, 0x42, 0xC0, 0xEC, 0x23,
|
||||
0x01, 0xA6, 0xE4, 0xC8, 0x01, 0xA4, 0xE4, 0xDB,
|
||||
0x12, 0xAA, 0xE3, 0x90, 0x11, 0xAA, 0xE3, 0x93,
|
||||
0x00, 0xA4, 0xE4, 0xE0, 0x06, 0xA8, 0xE5, 0xBA,
|
||||
0x5C, 0xC8, 0xEC, 0x15, 0x77, 0xCC, 0xEC, 0x00
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,221 @@
|
|||
const uint8_t image_9341_driveopen[] PROGMEM = {
|
||||
0xCE,0x12, 0xB5,0x30, 0xAC,0xEF, 0xAC,0xEF, 0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB5,0x0F,
|
||||
0xB5,0x0F, 0xB5,0x0F, 0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB5,0x0F,
|
||||
0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB5,0x0F, 0xB5,0x0F, 0xB5,0x0F, 0xB5,0x30, 0xB5,0x2F,
|
||||
0xB5,0x2F, 0xB5,0x30, 0xB5,0x50, 0xBD,0x50, 0xBD,0x50, 0xB5,0x50, 0xBD,0x50, 0xBD,0x51,
|
||||
0xBD,0x51, 0xBD,0x51, 0xBD,0x71, 0xBD,0x71, 0xBD,0x71, 0xBD,0x70, 0xBD,0x70, 0xC5,0x91,
|
||||
0xC5,0xB1, 0xC5,0xD1, 0xDE,0x53, 0xC5,0xB1, 0x83,0x8B, 0x7B,0x4A, 0x94,0x0C, 0x8B,0xEC,
|
||||
0x8B,0xEC, 0x8B,0xCB, 0x8B,0xEC, 0x8B,0xEC, 0x8B,0xEC, 0x8B,0xEC, 0x8B,0xCC, 0x8B,0xCB,
|
||||
0x8B,0xEC, 0x8B,0xEC, 0x8B,0xCB, 0x8B,0xEC, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCC, 0x8B,0xCC,
|
||||
0x8B,0xCC, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCB,
|
||||
0x8B,0xEC, 0x8B,0xEC, 0x8B,0xEC, 0x8B,0xEC, 0x8B,0xEC, 0x8B,0xEC, 0x8B,0xEB, 0x8B,0xEB,
|
||||
0x8B,0xEB, 0x8B,0xEB, 0x7B,0x6A, 0x7B,0x8A, 0xAC,0xCF, 0xDE,0x53, 0xC5,0xB2, 0x73,0x29,
|
||||
0x9C,0x4E, 0xAC,0xCF, 0xAC,0xCF, 0xA4,0xAF, 0xA4,0xAF, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0x8F,
|
||||
0xA4,0x8F, 0xA4,0x8F, 0xA4,0x8F, 0xA4,0x8F, 0xA4,0x8F, 0xA4,0x8F, 0x9C,0x8E, 0xA4,0x8E,
|
||||
0xA4,0x8E, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0xAE, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0x8E,
|
||||
0xA4,0x8E, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0x8E,
|
||||
0xA4,0x8E, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0x6E, 0x9C,0x8E, 0x94,0x4D, 0x62,0xC8, 0xB5,0x10,
|
||||
0xDE,0x53, 0xC5,0x91, 0x73,0x29, 0x9C,0x6F, 0xAC,0xCF, 0xAC,0xCF, 0xA4,0xAF, 0xA4,0xAE,
|
||||
0xA4,0x8E, 0xA4,0x8E, 0xA4,0xAF, 0xAC,0xAF, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0xAF, 0xA4,0x8E,
|
||||
0xA4,0x8E, 0xA4,0x8E, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0x8E, 0xA4,0xAE,
|
||||
0xA4,0x8E, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE,
|
||||
0xA4,0xAE, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0xAE, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0x8E, 0x9C,0x8E,
|
||||
0x94,0x4D, 0x6A,0xE8, 0xB5,0x10, 0xDE,0x53, 0xC5,0x91, 0x7B,0x49, 0xA4,0x8F, 0xAC,0xCF,
|
||||
0xAC,0xCF, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE,
|
||||
0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0x8E, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE,
|
||||
0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0xAE, 0xA4,0xAE,
|
||||
0xA4,0x8E, 0xA4,0x8E, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0x8E, 0xA4,0x8E,
|
||||
0xA4,0x8E, 0xA4,0x8E, 0x9C,0x8D, 0x9C,0x6E, 0x6B,0x08, 0xB5,0x10, 0xDE,0x53, 0xC5,0x91,
|
||||
0x73,0x29, 0xA4,0x8F, 0xAC,0xCF, 0xAC,0xCF, 0xAC,0xCF, 0xA4,0xAE, 0xA4,0xAE, 0xAC,0xCE,
|
||||
0xAC,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xCE, 0xA4,0xAE, 0xA4,0xAE, 0xAC,0xAE,
|
||||
0xA4,0xAE, 0xA4,0x8E, 0xAC,0xAE, 0xA4,0xAE, 0xAC,0xAE, 0xAC,0xAE, 0xA4,0xAE, 0xA4,0xAE,
|
||||
0xA4,0xAE, 0xA4,0xAE, 0xAC,0xCF, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE,
|
||||
0xA4,0xAE, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0xAE, 0x9C,0x8D, 0x9C,0x6E, 0x73,0x29,
|
||||
0xB5,0x30, 0xDE,0x53, 0xBD,0x91, 0x7B,0x49, 0xAC,0xEF, 0xB5,0x0F, 0xB5,0x0F, 0xB5,0x0F,
|
||||
0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB5,0x0F, 0xB5,0x0F, 0xB5,0x30, 0xB5,0x0F,
|
||||
0xAD,0x0F, 0xB4,0xEF, 0xB4,0xEF, 0xAC,0xCF, 0xB4,0xEF, 0xB4,0xEF, 0xB4,0xEF, 0xB4,0xEF,
|
||||
0xB4,0xEF, 0xB4,0xEF, 0xB5,0x0F, 0xB4,0xEF, 0xAC,0xEF, 0xAD,0x0F, 0xB5,0x0F, 0xB5,0x0F,
|
||||
0xB5,0x0F, 0xB5,0x0F, 0xB5,0x0F, 0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB4,0xF0, 0xAC,0xEF,
|
||||
0xA4,0xCE, 0xA4,0xAE, 0x7B,0x4A, 0xB5,0x30, 0xDE,0x53, 0xA4,0xAE, 0x72,0xE8, 0xC5,0xB2,
|
||||
0xC5,0x91, 0xC5,0x91, 0xC5,0x92, 0xC5,0xB2, 0xC5,0xB2, 0xC5,0xB2, 0xC5,0x91, 0xC5,0x91,
|
||||
0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xC5,0x91,
|
||||
0xC5,0x91, 0xC5,0x71, 0xC5,0x71, 0xC5,0x71, 0xC5,0x91, 0xC5,0x71, 0xC5,0x71, 0xC5,0x91,
|
||||
0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xC5,0x91,
|
||||
0xC5,0x92, 0xC5,0x72, 0xC5,0x71, 0xBD,0x50, 0xBD,0x50, 0x83,0x6A, 0xB5,0x10, 0xDE,0x53,
|
||||
0xA4,0xAD, 0x6A,0xC7, 0xBD,0x91, 0xBD,0x70, 0xBD,0x70, 0xBD,0x70, 0xBD,0x91, 0xBD,0x90,
|
||||
0xBD,0x90, 0xBD,0x71, 0xBD,0x71, 0xBD,0x71, 0xBD,0x71, 0xBD,0x70, 0xC5,0x71, 0xC5,0x71,
|
||||
0xC5,0x71, 0xC5,0x70, 0xBD,0x70, 0xBD,0x70, 0xC5,0x71, 0xBD,0x71, 0xC5,0x71, 0xC5,0x71,
|
||||
0xBD,0x71, 0xC5,0x71, 0xC5,0x71, 0xC5,0x70, 0xC5,0x70, 0xC5,0x70, 0xC5,0x70, 0xC5,0x70,
|
||||
0xBD,0x70, 0xC5,0x70, 0xBD,0x71, 0xBD,0x71, 0xBD,0x71, 0xBD,0x71, 0xBD,0x50, 0xBD,0x71,
|
||||
0x7B,0x29, 0xC5,0x91, 0xB5,0x0E, 0xC5,0xD2, 0x6A,0xE8, 0xBD,0x70, 0xBD,0x70, 0xBD,0x70,
|
||||
0xBD,0x70, 0xBD,0x70, 0xBD,0x70, 0xBD,0x70, 0xBD,0x71, 0xBD,0x71, 0xBD,0x70, 0xBD,0x70,
|
||||
0xBD,0x50, 0xBD,0x70, 0xBD,0x50, 0xBD,0x50, 0xBD,0x70, 0xBD,0x70, 0xBD,0x70, 0xBD,0x50,
|
||||
0xBD,0x50, 0xBD,0x50, 0xBD,0x50, 0xBD,0x50, 0xBD,0x70, 0xC5,0x70, 0xBD,0x50, 0xBD,0x50,
|
||||
0xBD,0x50, 0xBD,0x50, 0xBD,0x70, 0xBD,0x50, 0xBD,0x70, 0xBD,0x70, 0xBD,0x50, 0xBD,0x70,
|
||||
0xBD,0x70, 0xBD,0x50, 0xBD,0x50, 0x6A,0xE8, 0xCD,0xF2, 0xDE,0x73, 0xD6,0x33, 0x7B,0x49,
|
||||
0xC5,0x91, 0xC5,0xD1, 0xC5,0xD1, 0xC5,0xD1, 0xC5,0xB1, 0xC5,0xB1, 0xBD,0x70, 0xBD,0x91,
|
||||
0xC5,0xB2, 0xC5,0xB2, 0xC5,0x91, 0xC5,0x92, 0xBD,0x51, 0xBD,0x71, 0xBD,0x51, 0xBD,0x51,
|
||||
0xBD,0x71, 0xBD,0x71, 0xBD,0x50, 0xBD,0x71, 0xBD,0x71, 0xBD,0x91, 0xBD,0x91, 0xBD,0x91,
|
||||
0xBD,0x30, 0xBD,0x50, 0xC5,0x71, 0xBD,0x51, 0xBD,0x71, 0xBD,0x71, 0xBD,0x71, 0xBD,0x70,
|
||||
0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xBD,0x50, 0x62,0xA7, 0xBD,0x70,
|
||||
0xE6,0xB4, 0xD6,0x12, 0x7B,0x49, 0xC5,0xB2, 0xCD,0xD2, 0xCD,0xD2, 0xC5,0xB2, 0xCD,0xD2,
|
||||
0xBD,0x71, 0x9C,0x4D, 0xAC,0xCF, 0xAD,0x10, 0xA4,0xCF, 0x9C,0x6E, 0xB5,0x10, 0xA4,0xAF,
|
||||
0x9C,0x4D, 0xA4,0x8E, 0xA4,0x8E, 0x9C,0x4D, 0x9C,0x4D, 0x9C,0x4D, 0x94,0x2C, 0xAC,0xCF,
|
||||
0xA4,0x8E, 0xAC,0xEF, 0xAC,0xCF, 0xA4,0x8E, 0x9C,0x8E, 0xB5,0x10, 0xA4,0x8E, 0x9C,0x8E,
|
||||
0x9C,0x4D, 0x9C,0x4D, 0xA4,0x8E, 0xC5,0x91, 0xC5,0xB2, 0xC5,0x91, 0xC5,0x91, 0xBD,0x91,
|
||||
0xB5,0x2F, 0x62,0x86, 0xA4,0xAD, 0xDE,0x73, 0xC5,0x91, 0x73,0x08, 0xCD,0xF3, 0xCD,0xF3,
|
||||
0xCD,0xF3, 0xCD,0xF3, 0xCD,0xF3, 0xC5,0x91, 0xBD,0x71, 0xB5,0x51, 0xB5,0x10, 0xAC,0xCF,
|
||||
0xAC,0xF0, 0xBD,0x72, 0xAC,0xF0, 0xB5,0x10, 0xAC,0xF0, 0xB5,0x31, 0xAC,0xF0, 0xAC,0xF0,
|
||||
0xB5,0x10, 0xAC,0xF0, 0xBD,0x51, 0xAC,0xCF, 0xB5,0x10, 0xB5,0x51, 0xB5,0x30, 0xAC,0xEF,
|
||||
0xB5,0x30, 0xAD,0x10, 0xAD,0x10, 0xA4,0xCF, 0xA4,0x8E, 0xB5,0x30, 0xCD,0xF3, 0xCD,0xF3,
|
||||
0xCD,0xD2, 0xCD,0xD2, 0xC5,0xB2, 0xB5,0x30, 0x5A,0x66, 0x9C,0x4C, 0xC5,0xD1, 0xAC,0xEF,
|
||||
0x73,0x29, 0xE6,0x96, 0xE6,0xB6, 0xE6,0xB6, 0xE6,0xB6, 0xE6,0xB6, 0xE6,0xB6, 0xE6,0xB7,
|
||||
0xE6,0xB7, 0xE6,0x96, 0xE6,0x96, 0xE6,0x97, 0xE6,0xB7, 0xE6,0x96, 0xE6,0x96, 0xE6,0x96,
|
||||
0xE6,0x96, 0xE6,0x96, 0xE6,0x96, 0xE6,0x96, 0xE6,0x96, 0xDE,0x96, 0xDE,0x96, 0xDE,0x75,
|
||||
0xE6,0x96, 0xDE,0x76, 0xDE,0x76, 0xDE,0x76, 0xDE,0x96, 0xDE,0x76, 0xDE,0x96, 0xE6,0x96,
|
||||
0xDE,0x75, 0xE6,0x76, 0xE6,0x96, 0xD6,0x14, 0xD6,0x14, 0xCD,0xF2, 0xB5,0x10, 0x5A,0x66,
|
||||
0x9C,0x4C, 0xB5,0x4F, 0xAC,0xEE, 0x7B,0x6A, 0xBD,0x51, 0xBD,0x51, 0xBD,0x51, 0xBD,0x51,
|
||||
0xBD,0x51, 0xBD,0x51, 0xBD,0x51, 0xB5,0x51, 0x9C,0x6E, 0x94,0x2D, 0xAC,0xD0, 0xA4,0xAF,
|
||||
0x9C,0x6E, 0x9C,0x6E, 0xB5,0x31, 0x9C,0x6D, 0x94,0x0C, 0xA4,0xAF, 0xA4,0xAF, 0x9C,0x6E,
|
||||
0xAC,0xCF, 0xAC,0xCF, 0x9C,0x4D, 0x94,0x2D, 0x94,0x2D, 0x94,0x0D, 0x9C,0x4E, 0x94,0x2D,
|
||||
0xA4,0xAF, 0xB5,0x31, 0xB5,0x30, 0xB5,0x30, 0xB5,0x30, 0xB5,0x30, 0xB5,0x30, 0xB5,0x30,
|
||||
0xB5,0x50, 0xAC,0xCF, 0x5A,0x66, 0xA4,0x8D, 0xAC,0xEE, 0xAC,0xEF, 0x83,0x8A, 0xB5,0x10,
|
||||
0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB4,0xF0, 0xB5,0x10, 0xB5,0x10, 0x9C,0x4D,
|
||||
0x9C,0x6E, 0x94,0x2D, 0x94,0x0C, 0x8C,0x0C, 0x94,0x2D, 0xAC,0xCF, 0x94,0x2C, 0x8B,0xCB,
|
||||
0x9C,0x6D, 0x9C,0x6D, 0x8B,0xEB, 0x9C,0x4D, 0x9C,0x6E, 0x94,0x0C, 0x8B,0xEC, 0x94,0x2D,
|
||||
0x8B,0xCB, 0x8B,0xEC, 0x83,0xCB, 0x94,0x2D, 0xAC,0xEF, 0xAC,0xEF, 0xAC,0xEF, 0xAC,0xEF,
|
||||
0xAC,0xEF, 0xAC,0xEF, 0xAC,0xEF, 0xB5,0x10, 0xA4,0xAE, 0x62,0xA7, 0xA4,0xAE, 0xAC,0xEE,
|
||||
0xAC,0xEF, 0x8B,0xEB, 0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB5,0x0F, 0xAC,0xEF, 0xAC,0xEF,
|
||||
0xAC,0xEF, 0xAC,0xCF, 0xA4,0xCF, 0xA4,0xCF, 0xA4,0xAF, 0xA4,0x8F, 0xA4,0x8E, 0xA4,0xAF,
|
||||
0xA4,0xAF, 0xA4,0xAF, 0xA4,0x8E, 0xA4,0xAF, 0xA4,0xAF, 0xA4,0xAE, 0xA4,0xAF, 0xA4,0xAF,
|
||||
0xA4,0x8E, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0x8E, 0xA4,0xAE, 0xAC,0xCF, 0xAC,0xCF,
|
||||
0xAC,0xCF, 0xAC,0xCF, 0xAC,0xCF, 0xAC,0xEF, 0xAC,0xCF, 0xAC,0xCF, 0xAC,0xEF, 0x9C,0x4D,
|
||||
0x6A,0xC7, 0xA4,0xAE, 0xAC,0xCE, 0xAC,0xEF, 0x9C,0xAD, 0xD6,0x33, 0xCD,0xD2, 0xCD,0xD2,
|
||||
0xC5,0x91, 0xB5,0x30, 0xAC,0xCE, 0x9C,0x8D, 0x94,0x2C, 0x8B,0xEC, 0x8B,0xCB, 0x8B,0xEB,
|
||||
0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCB,
|
||||
0x8B,0xCB, 0x8B,0xEB, 0x8B,0xEB, 0x8C,0x0C, 0x94,0x2C, 0x94,0x2B, 0x9C,0x4C, 0x9C,0x6D,
|
||||
0xA4,0x8D, 0xA4,0xAD, 0xA4,0x8E, 0xA4,0x8E, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE,
|
||||
0xA4,0xAE, 0x9C,0x4D, 0x8B,0xCB, 0x7B,0x89, 0xA4,0x8D, 0xAC,0xCE, 0xBD,0x4F, 0xC5,0xD1,
|
||||
0xCD,0xD2, 0xE6,0xB5, 0xDE,0x74, 0xD6,0x33, 0xCD,0xD2, 0xC5,0xB1, 0xBD,0x50, 0xB5,0x30,
|
||||
0xB5,0x0F, 0xAC,0xEF, 0xAC,0xEF, 0xAC,0xEF, 0xAD,0x0F, 0xAC,0xEF, 0xAC,0xEF, 0xAC,0xEF,
|
||||
0xAC,0xEF, 0xAC,0xEF, 0xAC,0xEF, 0xAC,0xEF, 0xAC,0xEF, 0xAC,0xEF, 0xB5,0x0F, 0xB5,0x0F,
|
||||
0xB5,0x2F, 0xB5,0x50, 0xBD,0x70, 0xBD,0x91, 0xC5,0x91, 0xBD,0x91, 0xBD,0x71, 0xBD,0x71,
|
||||
0xBD,0x91, 0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xBD,0x70, 0xB5,0x0F, 0x9C,0x6D,
|
||||
0xB5,0x2F, 0xCD,0xD1, 0xE6,0x94, 0xE6,0xB5, 0xE6,0xD6, 0xE6,0xB5, 0xE6,0x95, 0xDE,0x74,
|
||||
0xDE,0x74, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x13, 0xD6,0x13, 0xCE,0x13, 0xCE,0x13,
|
||||
0xD6,0x33, 0xCE,0x13, 0xD6,0x33, 0xCE,0x13, 0xCE,0x13, 0xD6,0x13, 0xCE,0x13, 0xD6,0x13,
|
||||
0xD6,0x13, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x53, 0xDE,0x54, 0xDE,0x54,
|
||||
0xDE,0x54, 0xDE,0x54, 0xD6,0x53, 0xD6,0x53, 0xDE,0x53, 0xDE,0x54, 0xDE,0x54, 0xDE,0x53,
|
||||
0xDE,0x53, 0xD6,0x33, 0xB5,0x2F, 0xC5,0x91,
|
||||
};
|
||||
|
||||
const uint8_t image_9341_driveclosed[] PROGMEM = {
|
||||
0xCE,0x12, 0xB5,0x30, 0xAC,0xEF, 0xAC,0xEF, 0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB5,0x0F,
|
||||
0xB5,0x0F, 0xB5,0x0F, 0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB5,0x0F,
|
||||
0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB5,0x0F, 0xB5,0x0F, 0xB5,0x0F, 0xB5,0x30, 0xB5,0x2F,
|
||||
0xB5,0x2F, 0xB5,0x30, 0xB5,0x50, 0xBD,0x50, 0xBD,0x50, 0xB5,0x50, 0xBD,0x50, 0xBD,0x51,
|
||||
0xBD,0x51, 0xBD,0x51, 0xBD,0x71, 0xBD,0x71, 0xBD,0x71, 0xBD,0x70, 0xBD,0x70, 0xC5,0x91,
|
||||
0xC5,0xB1, 0xC5,0xD1, 0xDE,0x53, 0xC5,0xB1, 0x83,0x8B, 0x7B,0x4A, 0x94,0x0C, 0x8B,0xEC,
|
||||
0x8B,0xEC, 0x8B,0xCB, 0x8B,0xEC, 0x8B,0xEC, 0x8B,0xEC, 0x8B,0xEC, 0x8B,0xCC, 0x8B,0xCB,
|
||||
0x8B,0xEC, 0x8B,0xEC, 0x8B,0xCB, 0x8B,0xEC, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCC, 0x8B,0xCC,
|
||||
0x8B,0xCC, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCB, 0x8B,0xCB,
|
||||
0x8B,0xEC, 0x8B,0xEC, 0x8B,0xEC, 0x8B,0xEC, 0x8B,0xEC, 0x8B,0xEC, 0x8B,0xEB, 0x8B,0xEB,
|
||||
0x8B,0xEB, 0x8B,0xEB, 0x7B,0x6A, 0x7B,0x8A, 0xAC,0xCF, 0xDE,0x53, 0xC5,0xB2, 0x7B,0x49,
|
||||
0xC5,0x91, 0xC5,0xD1, 0xC5,0xD1, 0xC5,0xD1, 0xC5,0xB1, 0xC5,0xB1, 0xBD,0x70, 0xBD,0x91,
|
||||
0xC5,0xB2, 0xC5,0xB2, 0xC5,0x91, 0xC5,0x92, 0xBD,0x51, 0xBD,0x71, 0xBD,0x51, 0xBD,0x51,
|
||||
0xBD,0x71, 0xBD,0x71, 0xBD,0x50, 0xBD,0x71, 0xBD,0x71, 0xBD,0x91, 0xBD,0x91, 0xBD,0x91,
|
||||
0xBD,0x30, 0xBD,0x50, 0xC5,0x71, 0xBD,0x51, 0xBD,0x71, 0xBD,0x71, 0xBD,0x71, 0xBD,0x70,
|
||||
0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xC5,0x91, 0xBD,0x50, 0x62,0xA7, 0xB5,0x10,
|
||||
0xDE,0x53, 0xC5,0x91, 0x7B,0x49, 0xC5,0xB2, 0xCD,0xD2, 0xCD,0xD2, 0xC5,0xB2, 0xCD,0xD2,
|
||||
0xBD,0x71, 0x9C,0x4D, 0xAC,0xCF, 0xAD,0x10, 0xA4,0xCF, 0x9C,0x6E, 0xB5,0x10, 0xA4,0xAF,
|
||||
0x9C,0x4D, 0xA4,0x8E, 0xA4,0x8E, 0x9C,0x4D, 0x9C,0x4D, 0x9C,0x4D, 0x94,0x2C, 0xAC,0xCF,
|
||||
0xA4,0x8E, 0xAC,0xEF, 0xAC,0xCF, 0xA4,0x8E, 0x9C,0x8E, 0xB5,0x10, 0xA4,0x8E, 0x9C,0x8E,
|
||||
0x9C,0x4D, 0x9C,0x4D, 0xA4,0x8E, 0xC5,0x91, 0xC5,0xB2, 0xC5,0x91, 0xC5,0x91, 0xBD,0x91,
|
||||
0xB5,0x2F, 0x62,0x86, 0xB5,0x10, 0xDE,0x53, 0xC5,0x91, 0x73,0x08, 0xCD,0xF3, 0xCD,0xF3,
|
||||
0xCD,0xF3, 0xCD,0xF3, 0xCD,0xF3, 0xC5,0x91, 0xBD,0x71, 0xB5,0x51, 0xB5,0x10, 0xAC,0xCF,
|
||||
0xAC,0xF0, 0xBD,0x72, 0xAC,0xF0, 0xB5,0x10, 0xAC,0xF0, 0xB5,0x31, 0xAC,0xF0, 0xAC,0xF0,
|
||||
0xB5,0x10, 0xAC,0xF0, 0xBD,0x51, 0xAC,0xCF, 0xB5,0x10, 0xB5,0x51, 0xB5,0x30, 0xAC,0xEF,
|
||||
0xB5,0x30, 0xAD,0x10, 0xAD,0x10, 0xA4,0xCF, 0xA4,0x8E, 0xB5,0x30, 0xCD,0xF3, 0xCD,0xF3,
|
||||
0xCD,0xD2, 0xCD,0xD2, 0xC5,0xB2, 0xB5,0x30, 0x5A,0x66, 0xB5,0x10, 0xDE,0x53, 0xC5,0x91,
|
||||
0x73,0x29, 0xE6,0x96, 0xE6,0xB6, 0xE6,0xB6, 0xE6,0xB6, 0xE6,0xB6, 0xE6,0xB6, 0xE6,0xB7,
|
||||
0xE6,0xB7, 0xE6,0x96, 0xE6,0x96, 0xE6,0x97, 0xE6,0xB7, 0xE6,0x96, 0xE6,0x96, 0xE6,0x96,
|
||||
0xE6,0x96, 0xE6,0x96, 0xE6,0x96, 0xE6,0x96, 0xE6,0x96, 0xDE,0x96, 0xDE,0x96, 0xDE,0x75,
|
||||
0xE6,0x96, 0xDE,0x76, 0xDE,0x76, 0xDE,0x76, 0xDE,0x96, 0xDE,0x76, 0xDE,0x96, 0xE6,0x96,
|
||||
0xDE,0x75, 0xE6,0x76, 0xE6,0x96, 0xD6,0x14, 0xD6,0x14, 0xCD,0xF2, 0xB5,0x10, 0x5A,0x66,
|
||||
0xB5,0x30, 0xDE,0x53, 0xBD,0x91, 0x7B,0x6A, 0xBD,0x51, 0xBD,0x51, 0xBD,0x51, 0xBD,0x51,
|
||||
0xBD,0x51, 0xBD,0x51, 0xBD,0x51, 0xB5,0x51, 0x9C,0x6E, 0x94,0x2D, 0xAC,0xD0, 0xA4,0xAF,
|
||||
0x9C,0x6E, 0x9C,0x6E, 0xB5,0x31, 0x9C,0x6D, 0x94,0x0C, 0xA4,0xAF, 0xA4,0xAF, 0x9C,0x6E,
|
||||
0xAC,0xCF, 0xAC,0xCF, 0x9C,0x4D, 0x94,0x2D, 0x94,0x2D, 0x94,0x0D, 0x9C,0x4E, 0x94,0x2D,
|
||||
0xA4,0xAF, 0xB5,0x31, 0xB5,0x30, 0xB5,0x30, 0xB5,0x30, 0xB5,0x30, 0xB5,0x30, 0xB5,0x30,
|
||||
0xB5,0x50, 0xAC,0xCF, 0x5A,0x66, 0xB5,0x30, 0xDE,0x53, 0xA4,0xAE, 0x83,0x8A, 0xB5,0x10,
|
||||
0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB4,0xF0, 0xB5,0x10, 0xB5,0x10, 0x9C,0x4D,
|
||||
0x9C,0x6E, 0x94,0x2D, 0x94,0x0C, 0x8C,0x0C, 0x94,0x2D, 0xAC,0xCF, 0x94,0x2C, 0x8B,0xCB,
|
||||
0x9C,0x6D, 0x9C,0x6D, 0x8B,0xEB, 0x9C,0x4D, 0x9C,0x6E, 0x94,0x0C, 0x8B,0xEC, 0x94,0x2D,
|
||||
0x8B,0xCB, 0x8B,0xEC, 0x83,0xCB, 0x94,0x2D, 0xAC,0xEF, 0xAC,0xEF, 0xAC,0xEF, 0xAC,0xEF,
|
||||
0xAC,0xEF, 0xAC,0xEF, 0xAC,0xEF, 0xB5,0x10, 0xA4,0xAE, 0x62,0xA7, 0xB5,0x10, 0xDE,0x53,
|
||||
0xA4,0xAD, 0x8B,0xEB, 0xB5,0x10, 0xB5,0x10, 0xB5,0x10, 0xB5,0x0F, 0xAC,0xEF, 0xAC,0xEF,
|
||||
0xAC,0xEF, 0xAC,0xCF, 0xA4,0xCF, 0xA4,0xCF, 0xA4,0xAF, 0xA4,0x8F, 0xA4,0x8E, 0xA4,0xAF,
|
||||
0xA4,0xAF, 0xA4,0xAF, 0xA4,0x8E, 0xA4,0xAF, 0xA4,0xAF, 0xA4,0xAE, 0xA4,0xAF, 0xA4,0xAF,
|
||||
0xA4,0x8E, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0xAE, 0xA4,0x8E, 0xA4,0xAE, 0xAC,0xCF, 0xAC,0xCF,
|
||||
0xAC,0xCF, 0xAC,0xCF, 0xAC,0xCF, 0xAC,0xEF, 0xAC,0xCF, 0xAC,0xCF, 0xAC,0xEF, 0x9C,0x4D,
|
||||
0x6A,0xC7, 0xA4,0xAD, 0xA4,0xAD, 0xC5,0xD2, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67,
|
||||
0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67,
|
||||
0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67,
|
||||
0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67,
|
||||
0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67,
|
||||
0x52,0x67, 0x52,0x67, 0x52,0x67, 0x52,0x67, 0xA4,0xAD, 0xDE,0x53, 0xD6,0x33, 0x62,0xE9,
|
||||
0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9,
|
||||
0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9,
|
||||
0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9,
|
||||
0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9,
|
||||
0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0x62,0xE9, 0xA4,0xAD,
|
||||
0xEE,0xF6, 0xD6,0x12, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2,
|
||||
0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2,
|
||||
0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2,
|
||||
0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2,
|
||||
0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2, 0xC5,0xD2,
|
||||
0xC5,0xD2, 0xC5,0xD2, 0xA4,0xAD, 0xEE,0xF6, 0xC5,0x91, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2,
|
||||
0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2,
|
||||
0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2,
|
||||
0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2,
|
||||
0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2,
|
||||
0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0xCD,0xF2, 0x9C,0x4C, 0xEE,0xF6, 0xAC,0xEF,
|
||||
0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13,
|
||||
0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13,
|
||||
0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13,
|
||||
0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13,
|
||||
0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13, 0xD6,0x13,
|
||||
0x9C,0x4C, 0xEE,0xF6, 0xAC,0xEE, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33,
|
||||
0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33,
|
||||
0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33,
|
||||
0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33,
|
||||
0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33,
|
||||
0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xA4,0x8D, 0xDE,0x53, 0xAC,0xEF, 0xD6,0x53, 0xD6,0x53,
|
||||
0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53,
|
||||
0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53,
|
||||
0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53,
|
||||
0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53,
|
||||
0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xA4,0xAE, 0xDE,0x53,
|
||||
0xAC,0xEF, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53,
|
||||
0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53,
|
||||
0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53,
|
||||
0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53,
|
||||
0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53,
|
||||
0xDE,0x53, 0xA4,0xAE, 0xDE,0x53, 0xAC,0xEF, 0xDE,0x53, 0xDE,0x53, 0xDE,0x54, 0xDE,0x54,
|
||||
0xDE,0x53, 0xDE,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33,
|
||||
0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33,
|
||||
0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x53,
|
||||
0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53,
|
||||
0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x33, 0xA4,0x8D, 0xDE,0x53, 0xBD,0x4F, 0xDE,0x53,
|
||||
0xDE,0x53, 0xDE,0x54, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53,
|
||||
0xDE,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xD6,0x53,
|
||||
0xD6,0x53, 0xD6,0x53, 0xD6,0x53, 0xDE,0x53, 0xD6,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53,
|
||||
0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53,
|
||||
0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0xDE,0x53, 0x9C,0x6D,
|
||||
0xDE,0x53, 0xCD,0xD1, 0xE6,0x94, 0xE6,0xB5, 0xE6,0xD6, 0xE6,0xB5, 0xE6,0x95, 0xDE,0x74,
|
||||
0xDE,0x74, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x13, 0xD6,0x13, 0xCE,0x13, 0xCE,0x13,
|
||||
0xD6,0x33, 0xCE,0x13, 0xD6,0x33, 0xCE,0x13, 0xCE,0x13, 0xD6,0x13, 0xCE,0x13, 0xD6,0x13,
|
||||
0xD6,0x13, 0xD6,0x33, 0xCE,0x13, 0xCE,0x13, 0xD6,0x13, 0xCE,0x13, 0xD6,0x13, 0xD6,0x13,
|
||||
0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x33, 0xD6,0x53, 0xDE,0x54, 0xDE,0x54, 0xDE,0x54,
|
||||
0xDE,0x54, 0xD6,0x53, 0xB5,0x2F, 0xDE,0x53,
|
||||
};
|
29589
images.cpp
29589
images.cpp
File diff suppressed because it is too large
Load Diff
61
images.h
61
images.h
|
@ -1,19 +1,60 @@
|
|||
#ifndef __IMAGES_H
|
||||
#define __IMAGES_H
|
||||
|
||||
#ifdef TEENSYDUINO
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#define DBITMAP_HEIGHT 240
|
||||
#define DBITMAP_WIDTH 320
|
||||
// RGB
|
||||
extern const uint8_t displayBitmap[];
|
||||
#define SCREENINSET_8875_X (121)
|
||||
#define SCREENINSET_8875_Y (47)
|
||||
#define SCREENINSET_9341_X (18)
|
||||
#define SCREENINSET_9341_Y (13)
|
||||
|
||||
// 43 x 20 RGB
|
||||
extern const uint8_t driveLatch[];
|
||||
// drive activity LED positions
|
||||
#define LED_HEIGHT_8875 9
|
||||
#define LED_WIDTH_8875 17
|
||||
#define LED1_X_8875 48
|
||||
#define LED2_X_8875 48
|
||||
#define LED1_Y_8875 68
|
||||
#define LED2_Y_8875 117
|
||||
|
||||
// 43 x 20 RGB
|
||||
extern const uint8_t driveLatchOpen[];
|
||||
#define LED_HEIGHT_9341 1
|
||||
#define LED_WIDTH_9341 6
|
||||
#define LED1_X_9341 125
|
||||
#define LED2_X_9341 (125+135)
|
||||
#define LED1_Y_9341 213
|
||||
#define LED2_Y_9341 213
|
||||
|
||||
// 10 x 11, RGBA
|
||||
extern const uint8_t appleBitmap[];
|
||||
// These are the ABSTRACTED constants that AppleUI uses to tell the
|
||||
// display what it wants redrawn via drawUIImage(uint8_t imageIdx)
|
||||
enum {
|
||||
IMG_SHELL = 0, // previously displayBitmap
|
||||
IMG_D1OPEN = 1,
|
||||
IMG_D1CLOSED = 2,
|
||||
IMG_D2OPEN = 3,
|
||||
IMG_D2CLOSED = 4,
|
||||
IMG_APPLEBATTERY = 5
|
||||
};
|
||||
|
||||
// These are the DISPLAY-SPECIFIC constants that are used to retrieve
|
||||
// a specific image from storage from within drawUIImage itself
|
||||
enum {
|
||||
IMG_8875_SHELL = 0,
|
||||
IMG_8875_D1OPEN = 1,
|
||||
IMG_8875_D1CLOSED = 2,
|
||||
IMG_8875_D2OPEN = 3,
|
||||
IMG_8875_D2CLOSED = 4,
|
||||
IMG_8875_APPLEBATTERY = 5,
|
||||
IMG_9341_SHELL = 6,
|
||||
IMG_9341_D1OPEN = 7,
|
||||
IMG_9341_D1CLOSED = 8,
|
||||
IMG_9341_D2OPEN = 7, // repeat of d1; they're the same image
|
||||
IMG_9341_D2CLOSED = 8,
|
||||
IMG_9341_APPLEBATTERY = 9
|
||||
};
|
||||
|
||||
bool getImageInfoAndData(uint8_t imgnum, uint16_t *width, uint16_t *height, uint8_t **dataptr);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
#include "physicaldisplay.h"
|
||||
#include "globals.h"
|
||||
#include "applevm.h"
|
||||
#include "appleui.h"
|
||||
|
||||
#include "font.h"
|
||||
|
||||
void PhysicalDisplay::drawCharacter(uint8_t mode, uint16_t x, uint16_t y, char c)
|
||||
{
|
||||
int8_t xsize = 8,
|
||||
ysize = 0x07;
|
||||
|
||||
uint16_t offPixel, onPixel;
|
||||
switch (mode) {
|
||||
case M_NORMAL:
|
||||
onPixel = 0xFFFF;
|
||||
offPixel = 0x0010;
|
||||
break;
|
||||
case M_SELECTED:
|
||||
onPixel = 0x0000;
|
||||
offPixel = 0xFFFF;
|
||||
break;
|
||||
case M_DISABLED:
|
||||
default:
|
||||
onPixel = 0x7BEF;
|
||||
offPixel = 0x0000;
|
||||
break;
|
||||
case M_SELECTDISABLED:
|
||||
onPixel = 0x7BEF;
|
||||
offPixel = 0xFFE0;
|
||||
break;
|
||||
case M_PLAIN:
|
||||
onPixel = 0xFFFF;
|
||||
offPixel = 0x0000;
|
||||
break;
|
||||
}
|
||||
|
||||
const unsigned char *ch = asciiToAppleGlyph(c);
|
||||
for (int8_t y_off = 0; y_off <= ysize; y_off++) {
|
||||
for (int8_t x_off = 0; x_off <= xsize; x_off++) {
|
||||
if (*ch & (1 << (x_off))) {
|
||||
drawPixel(x+x_off, y+y_off, onPixel);
|
||||
} else {
|
||||
drawPixel(x+x_off, y+y_off, offPixel);
|
||||
}
|
||||
}
|
||||
ch++;
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicalDisplay::drawString(uint8_t mode, uint16_t x, uint16_t y, const char *str)
|
||||
{
|
||||
int8_t xsize = 8; // width of a char in this font
|
||||
|
||||
for (int8_t i=0; i<strlen(str); i++) {
|
||||
drawCharacter(mode, x, y, str[i]);
|
||||
x += xsize;
|
||||
if (x >= 320-xsize) break; // FIXME needs to know the actual display size?
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicalDisplay::redraw()
|
||||
{
|
||||
if (g_ui) {
|
||||
g_ui->drawStaticUIElement(UIeOverlay);
|
||||
|
||||
if (g_vm) {
|
||||
g_ui->drawOnOffUIElement(UIeDisk1_state, ((AppleVM *)g_vm)->DiskName(0)[0] == '\0');
|
||||
g_ui->drawOnOffUIElement(UIeDisk2_state, ((AppleVM *)g_vm)->DiskName(1)[0] == '\0');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,21 +10,21 @@ class PhysicalDisplay {
|
|||
PhysicalDisplay() { overlayMessage[0] = '\0'; }
|
||||
virtual ~PhysicalDisplay() {};
|
||||
|
||||
virtual void flush() = 0; // flush any pending drawings
|
||||
virtual void redraw() = 0; // total redraw, assuming nothing
|
||||
virtual void redraw(); // total redraw, assuming nothing
|
||||
virtual void blit() = 0; // blit everything to the display (including UI area)
|
||||
virtual void blit(AiieRect r) = 0; // blit a piece of the VM area to the display
|
||||
virtual void flush() = 0;
|
||||
|
||||
virtual void drawUIImage(uint8_t imageIdx) = 0;
|
||||
virtual void drawDriveActivity(bool drive0, bool drive1) = 0;
|
||||
// FIXME: drawImageOfSizeAt should probably be private now
|
||||
virtual void drawImageOfSizeAt(const uint8_t *img, uint16_t sizex, uint16_t sizey, uint16_t wherex, uint16_t wherey) = 0;
|
||||
|
||||
virtual void drawCharacter(uint8_t mode, uint16_t x, uint16_t y, char c) = 0;
|
||||
virtual void drawString(uint8_t mode, uint16_t x, uint16_t y, const char *str) = 0;
|
||||
virtual void drawCharacter(uint8_t mode, uint16_t x, uint16_t y, char c);
|
||||
virtual void drawString(uint8_t mode, uint16_t x, uint16_t y, const char *str);
|
||||
virtual void debugMsg(const char *msg) { strncpy(overlayMessage, msg, sizeof(overlayMessage));overlayMessage[strlen(overlayMessage)] = 0; }
|
||||
|
||||
virtual void drawPixel(uint16_t x, uint16_t y, uint16_t color) = 0;
|
||||
virtual void drawPixel(uint16_t x, uint16_t y, uint8_t r, uint8_t g, uint8_t b) = 0;
|
||||
|
||||
virtual void drawUIPixel(uint16_t x, uint16_t y, uint16_t color) = 0;
|
||||
// virtual void drawPixel(uint16_t x, uint16_t y, uint8_t r, uint8_t g, uint8_t b) = 0;
|
||||
|
||||
virtual void clrScr(uint8_t coloridx) = 0;
|
||||
|
||||
|
@ -32,7 +32,6 @@ class PhysicalDisplay {
|
|||
|
||||
// First, methods that expect *us* to pixel-double the width...
|
||||
virtual void cacheDoubleWidePixel(uint16_t x, uint16_t y, uint8_t color) = 0;
|
||||
virtual void cache2DoubleWidePixels(uint16_t x, uint16_t y, uint8_t colorA, uint8_t colorB) = 0;
|
||||
|
||||
// Then the direct-pixel methods
|
||||
virtual void cachePixel(uint16_t x, uint16_t y, uint8_t color) = 0;
|
||||
|
|
18
sdl/aiie.cpp
18
sdl/aiie.cpp
|
@ -227,9 +227,8 @@ struct timespec runDisplay(struct timespec now)
|
|||
g_ui->blit();
|
||||
g_vm->vmdisplay->lockDisplay();
|
||||
if (g_vm->vmdisplay->needsRedraw()) {
|
||||
AiieRect what = g_vm->vmdisplay->getDirtyRect();
|
||||
g_vm->vmdisplay->didRedraw();
|
||||
g_display->blit(what);
|
||||
g_display->blit();
|
||||
}
|
||||
g_vm->vmdisplay->unlockDisplay();
|
||||
|
||||
|
@ -372,9 +371,24 @@ void loop()
|
|||
}
|
||||
}
|
||||
|
||||
bool use8875 = true;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
_init_darwin_shim();
|
||||
|
||||
/* Look for flags first and strip them out of argv/argc if present, leaving
|
||||
* just filenames for disks to have been inserted */
|
||||
if (argc > 1 && !strcmp(argv[1], "-9")) {
|
||||
argc--;
|
||||
argv++;
|
||||
use8875 = false;
|
||||
}
|
||||
else if (argc > 1 && !strcmp(argv[1], "-8")) {
|
||||
argc--;
|
||||
argv++;
|
||||
use8875 = true;
|
||||
}
|
||||
|
||||
SDL_Init(SDL_INIT_EVERYTHING);
|
||||
|
||||
|
|
|
@ -7,16 +7,113 @@
|
|||
#include "applevm.h"
|
||||
|
||||
#include "apple/appleui.h"
|
||||
// FIXME should be able to omit this include and rely on the xterns, which
|
||||
// would prove it's linking properly
|
||||
#include "apple/font.h"
|
||||
extern const unsigned char ucase_glyphs[512];
|
||||
extern const unsigned char lcase_glyphs[256];
|
||||
extern const unsigned char mousetext_glyphs[256];
|
||||
extern const unsigned char interface_glyphs[256];
|
||||
|
||||
#define SCREENINSET_X (18*SDLDISPLAY_SCALE)
|
||||
#define SCREENINSET_Y (13*SDLDISPLAY_SCALE)
|
||||
#include "images.h"
|
||||
|
||||
#define RA8875_WIDTH 800
|
||||
#define RA8875_HEIGHT 480
|
||||
#define ILI9341_WIDTH 320
|
||||
#define ILI9341_HEIGHT 240
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
|
||||
static void rgb_to_hsv(double r, double g, double b, double *h, double *s, double *v)
|
||||
{
|
||||
// Range for these equations is [0..1] not [0..255]
|
||||
r = r / 255.0;
|
||||
g = g / 255.0;
|
||||
b = b / 255.0;
|
||||
|
||||
// h, s, v = hue, saturation, value
|
||||
double cmax = max(r, max(g, b)); // maximum of r, g, b
|
||||
double cmin = min(r, min(g, b)); // minimum of r, g, b
|
||||
double diff = cmax - cmin; // diff of cmax and cmin.
|
||||
|
||||
// if cmax and cmax are equal then h = 0
|
||||
if (cmax == cmin)
|
||||
*h = 0;
|
||||
|
||||
// if cmax equal r then compute h
|
||||
else if (cmax == r)
|
||||
*h = (int)(60 * ((g - b) / diff) + 360) % 360;
|
||||
|
||||
// if cmax equal g then compute h
|
||||
else if (cmax == g)
|
||||
*h = (int)(60 * ((b - r) / diff) + 120) % 360;
|
||||
|
||||
// if cmax equal b then compute h
|
||||
else if (cmax == b)
|
||||
*h = (int)(60 * ((r - g) / diff) + 240) % 360;
|
||||
|
||||
// if cmax equal zero
|
||||
if (cmax == 0)
|
||||
*s = 0;
|
||||
else
|
||||
*s = (diff / cmax) * 100;
|
||||
|
||||
// compute v
|
||||
*v = cmax * 100;
|
||||
}
|
||||
|
||||
static void hsv_to_rgb(double H, double S, double V, uint8_t *R, uint8_t *G, uint8_t *B)
|
||||
{
|
||||
float s = S/100;
|
||||
float v = V/100;
|
||||
float C = s*v;
|
||||
float X = C*(1-fabs(fmod(H/60.0, 2)-1));
|
||||
float m = v-C;
|
||||
float r,g,b;
|
||||
if(H >= 0 && H < 60){
|
||||
r = C,g = X,b = 0;
|
||||
}
|
||||
else if(H >= 60 && H < 120){
|
||||
r = X,g = C,b = 0;
|
||||
}
|
||||
else if(H >= 120 && H < 180){
|
||||
r = 0,g = C,b = X;
|
||||
}
|
||||
else if(H >= 180 && H < 240){
|
||||
r = 0,g = X,b = C;
|
||||
}
|
||||
else if(H >= 240 && H < 300){
|
||||
r = X,g = 0,b = C;
|
||||
}
|
||||
else{
|
||||
r = C,g = 0,b = X;
|
||||
}
|
||||
*R = (r+m)*255;
|
||||
*G = (g+m)*255;
|
||||
*B = (b+m)*255;
|
||||
}
|
||||
|
||||
// blend two 24-bit packed colors
|
||||
uint32_t blendColors(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint8_t r1, r2, g1, g2, b1, b2;
|
||||
r1 = (a & 0xFF0000) >> 16;
|
||||
g1 = (a & 0x00FF00) >> 8;
|
||||
b1 = (a & 0x0000FF);
|
||||
r2 = (b & 0xFF0000) >> 16;
|
||||
g2 = (b & 0x00FF00) >> 8;
|
||||
b2 = (b & 0x0000FF);
|
||||
|
||||
double h1, s1, v1, h2, s2, v2;
|
||||
rgb_to_hsv(r1, g1, b1, &h1, &s1, &v1);
|
||||
rgb_to_hsv(r2, g2, b2, &h2, &s2, &v2);
|
||||
|
||||
hsv_to_rgb((h1+h2)/2, (s1+s2)/2, (v1+v2)/2, &r1, &g1, &b1);
|
||||
uint32_t ret = (r1 << 16) | (g1 << 8) | (b1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern bool use8875;
|
||||
|
||||
// RGB map of each of the lowres colors
|
||||
const uint8_t loresPixelColors[16][3] = { { 0, 0, 0 }, // black
|
||||
|
@ -50,13 +147,36 @@ const uint8_t loresPixelColors[16][3] = { { 0, 0, 0 }, // black
|
|||
|
||||
SDLDisplay::SDLDisplay()
|
||||
{
|
||||
memset(videoBuffer, 0, sizeof(videoBuffer));
|
||||
driveIndicator[0] = driveIndicator[1] = true; // assume on so they will redraw the first time
|
||||
|
||||
// FIXME: abstract constants
|
||||
shellImage = NULL;
|
||||
d1OpenImage = d1ClosedImage = d2OpenImage = d2ClosedImage = NULL;
|
||||
appleImage = NULL;
|
||||
|
||||
if (use8875) {
|
||||
videoBuffer = (uint32_t *)calloc(RA8875_HEIGHT * RA8875_WIDTH, sizeof(uint32_t));
|
||||
getImageInfoAndData(IMG_8875_SHELL, &shellWidth, &shellHeight, &shellImage);
|
||||
getImageInfoAndData(IMG_8875_D1OPEN, &driveWidth, &driveHeight, &d1OpenImage);
|
||||
getImageInfoAndData(IMG_8875_D1CLOSED, &driveWidth, &driveHeight, &d1ClosedImage);
|
||||
getImageInfoAndData(IMG_8875_D2OPEN, &driveWidth, &driveHeight, &d2OpenImage);
|
||||
getImageInfoAndData(IMG_8875_D2CLOSED, &driveWidth, &driveHeight, &d2ClosedImage);
|
||||
getImageInfoAndData(IMG_8875_APPLEBATTERY, &appleImageWidth, &appleImageHeight, &appleImage);
|
||||
} else {
|
||||
videoBuffer = (uint32_t *)calloc(ILI9341_HEIGHT * ILI9341_WIDTH, sizeof(uint32_t));
|
||||
getImageInfoAndData(IMG_9341_SHELL, &shellWidth, &shellHeight, &shellImage);
|
||||
getImageInfoAndData(IMG_9341_D1OPEN, &driveWidth, &driveHeight, &d1OpenImage);
|
||||
getImageInfoAndData(IMG_9341_D1CLOSED, &driveWidth, &driveHeight, &d1ClosedImage);
|
||||
getImageInfoAndData(IMG_9341_D2OPEN, &driveWidth, &driveHeight, &d2OpenImage);
|
||||
getImageInfoAndData(IMG_9341_D2CLOSED, &driveWidth, &driveHeight, &d2ClosedImage);
|
||||
getImageInfoAndData(IMG_9341_APPLEBATTERY, &appleImageWidth, &appleImageHeight, &appleImage);
|
||||
}
|
||||
|
||||
|
||||
screen = SDL_CreateWindow("Aiie!",
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDLDISPLAY_WIDTH, SDLDISPLAY_HEIGHT,
|
||||
use8875 ? RA8875_WIDTH : ILI9341_WIDTH*2,
|
||||
use8875 ? RA8875_HEIGHT : ILI9341_HEIGHT*2,
|
||||
SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE);
|
||||
|
||||
// SDL_RENDERER_SOFTWARE because, at least on my Mac, this has some
|
||||
|
@ -67,10 +187,10 @@ SDLDisplay::SDLDisplay()
|
|||
SDL_RenderPresent(renderer); // perform the render
|
||||
|
||||
buffer = SDL_CreateTexture(renderer,
|
||||
SDL_PIXELFORMAT_RGB888,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
SDLDISPLAY_WIDTH,
|
||||
SDLDISPLAY_HEIGHT);
|
||||
SDL_PIXELFORMAT_RGB888,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
use8875 ? RA8875_WIDTH : ILI9341_WIDTH,
|
||||
use8875 ? RA8875_HEIGHT : ILI9341_HEIGHT);
|
||||
}
|
||||
|
||||
SDLDisplay::~SDLDisplay()
|
||||
|
@ -81,40 +201,78 @@ SDLDisplay::~SDLDisplay()
|
|||
void SDLDisplay::flush()
|
||||
{
|
||||
blit();
|
||||
SDL_RenderPresent(renderer);
|
||||
// blit() called SDL_RenderPresent already
|
||||
// SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
void SDLDisplay::redraw()
|
||||
void SDLDisplay::drawUIImage(uint8_t imageIdx)
|
||||
{
|
||||
// primarily for the device, where it's in and out of the
|
||||
// bios. Draws the background image.
|
||||
g_ui->drawStaticUIElement(UIeOverlay);
|
||||
|
||||
if (g_vm && g_ui) {
|
||||
// determine whether or not a disk is inserted & redraw each drive
|
||||
g_ui->drawOnOffUIElement(UIeDisk1_state, ((AppleVM *)g_vm)->DiskName(0)[0] == '\0');
|
||||
g_ui->drawOnOffUIElement(UIeDisk2_state, ((AppleVM *)g_vm)->DiskName(1)[0] == '\0');
|
||||
switch (imageIdx) {
|
||||
case IMG_SHELL:
|
||||
drawImageOfSizeAt(shellImage, shellWidth, shellHeight, 0, 0);
|
||||
break;
|
||||
case IMG_D1OPEN:
|
||||
drawImageOfSizeAt(d1OpenImage, driveWidth, driveHeight,
|
||||
use8875 ? 4 : 55,
|
||||
use8875 ? 67 : 216);
|
||||
break;
|
||||
case IMG_D1CLOSED:
|
||||
drawImageOfSizeAt(d1ClosedImage, driveWidth, driveHeight,
|
||||
use8875 ? 4 : 189,
|
||||
use8875 ? 116 : 216);
|
||||
break;
|
||||
case IMG_D2OPEN:
|
||||
drawImageOfSizeAt(d2OpenImage, driveWidth, driveHeight,
|
||||
use8875 ? 4 : 189,
|
||||
use8875 ? 116 : 216);
|
||||
break;
|
||||
case IMG_D2CLOSED:
|
||||
drawImageOfSizeAt(d2ClosedImage, driveWidth, driveHeight,
|
||||
use8875 ? 4 : 189,
|
||||
use8875 ? 116 : 216);
|
||||
break;
|
||||
case IMG_APPLEBATTERY:
|
||||
// FIXME ***
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SDLDisplay::drawDriveActivity(bool drive0, bool drive1)
|
||||
{
|
||||
if (drive0 != driveIndicator[0]) {
|
||||
for (int y=0; y<(use8875 ? LED_HEIGHT_8875 : LED_HEIGHT_9341); y++) {
|
||||
for (int x=0; x<(use8875 ? LED_WIDTH_8875 : LED_WIDTH_9341); x++) {
|
||||
// FIXME this isn't working, not sure why
|
||||
// ... is it because nothing calls flush()?
|
||||
drawPixel(x+(use8875 ? LED1_X_8875 : LED1_X_9341), y+(use8875 ? LED1_Y_8875 : LED1_Y_9341), drive0 ? 0xFA00 : 0x0000);
|
||||
}
|
||||
}
|
||||
driveIndicator[0] = drive0;
|
||||
}
|
||||
|
||||
if (drive1 != driveIndicator[1]) {
|
||||
for (int y=0; y<(use8875 ? LED_HEIGHT_8875 : LED_HEIGHT_9341); y++) {
|
||||
for (int x=0; x<(use8875 ? LED_WIDTH_8875 : LED_WIDTH_9341); x++) {
|
||||
drawPixel(x+(use8875 ? LED2_X_8875 : LED2_X_9341), y+(use8875 ? LED2_Y_8875 : LED2_Y_9341), drive0 ? 0xFA00 : 0x0000);
|
||||
}
|
||||
}
|
||||
|
||||
driveIndicator[1] = drive1;
|
||||
}
|
||||
}
|
||||
|
||||
// drawImageOfSizeAt will horizontally scale out the image b/c the
|
||||
// images themselves aren't aware of the double resolution. This is an
|
||||
// inconsistency that probably should be addressed. FIXME?
|
||||
void SDLDisplay::drawImageOfSizeAt(const uint8_t *img,
|
||||
uint16_t sizex, uint16_t sizey,
|
||||
uint16_t wherex, uint16_t wherey)
|
||||
{
|
||||
const uint8_t *p = img;
|
||||
for (uint16_t y=0; y<sizey; y++) {
|
||||
for (uint16_t x=0; x<sizex; x++) {
|
||||
const uint8_t *p = &img[(y * sizex + x)*3];
|
||||
p = &img[(y * sizex + x)*3];
|
||||
|
||||
// FIXME this assumes scale == 2
|
||||
|
||||
videoBuffer[(y+wherey)*SDLDISPLAY_SCALE][(x+wherex)*SDLDISPLAY_SCALE] = packColor32(p);
|
||||
videoBuffer[(y+wherey)*SDLDISPLAY_SCALE][(x+wherex)*SDLDISPLAY_SCALE+1] = packColor32(p);
|
||||
videoBuffer[(y+wherey)*SDLDISPLAY_SCALE+1][(x+wherex)*SDLDISPLAY_SCALE] = packColor32(p);
|
||||
videoBuffer[(y+wherey)*SDLDISPLAY_SCALE+1][(x+wherex)*SDLDISPLAY_SCALE+1] = packColor32(p);
|
||||
uint16_t v = *p++;
|
||||
v<<=8;
|
||||
v |= *p++;
|
||||
videoBuffer[(y+wherey) * (use8875 ? RA8875_WIDTH : ILI9341_WIDTH) +
|
||||
(x+wherex)] = color16To32(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -128,121 +286,36 @@ void SDLDisplay::blit()
|
|||
(void **)&pixels,
|
||||
&pitch);
|
||||
// FIXME what if pitch isn't as expected? Should be width*4
|
||||
|
||||
memcpy(pixels, videoBuffer, sizeof(videoBuffer));
|
||||
|
||||
static uint32_t bufsize = 0;
|
||||
if (!bufsize) {
|
||||
bufsize = use8875 ? (RA8875_WIDTH*RA8875_HEIGHT*sizeof(uint32_t)) : (ILI9341_HEIGHT*ILI9341_WIDTH*sizeof(uint32_t));
|
||||
}
|
||||
memcpy(pixels, videoBuffer, bufsize);
|
||||
|
||||
SDL_UnlockTexture(buffer);
|
||||
SDL_RenderCopy(renderer, buffer, NULL, NULL);
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
// Blit the videoBuffer to the display device, in the rect given
|
||||
void SDLDisplay::blit(AiieRect r)
|
||||
{
|
||||
blit();
|
||||
/*
|
||||
if (overlayMessage[0]) {
|
||||
drawString(M_SELECTDISABLED, 1, 240 - 16 - 12, overlayMessage);
|
||||
}
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
*/
|
||||
}
|
||||
|
||||
inline void putpixel(SDL_Renderer *renderer, int x, int y, uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
SDL_SetRenderDrawColor(renderer, r, g, b, 255);
|
||||
SDL_RenderDrawPoint(renderer, x, y);
|
||||
}
|
||||
|
||||
void SDLDisplay::drawUIPixel(uint16_t x, uint16_t y, uint16_t color)
|
||||
{
|
||||
for (int yoff=0; yoff<SDLDISPLAY_SCALE; yoff++) {
|
||||
for (int xoff=0; xoff<SDLDISPLAY_SCALE; xoff++) {
|
||||
videoBuffer[y*SDLDISPLAY_SCALE+yoff][x*SDLDISPLAY_SCALE+xoff] = color16To32(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SDLDisplay::drawPixel(uint16_t x, uint16_t y, uint16_t color)
|
||||
{
|
||||
uint8_t
|
||||
r = (color & 0xF800) >> 8,
|
||||
g = (color & 0x7E0) >> 3,
|
||||
b = (color & 0x1F) << 3;
|
||||
|
||||
// Pixel-doubling vertically and horizontally, based on scale
|
||||
for (int yoff=0; yoff<SDLDISPLAY_SCALE; yoff++) {
|
||||
for (int xoff=0; xoff<SDLDISPLAY_SCALE; xoff++) {
|
||||
putpixel(renderer, x+xoff, yoff+y*SDLDISPLAY_SCALE, r, g, b);
|
||||
}
|
||||
if (use8875 && (x >= RA8875_WIDTH || y >= RA8875_HEIGHT)) {
|
||||
printf("err: out of bounds drawing\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void SDLDisplay::drawPixel(uint16_t x, uint16_t y, uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
// Pixel-doubling horizontally and vertically, based on scale
|
||||
for (int yoff=0; yoff<SDLDISPLAY_SCALE; yoff++) {
|
||||
for (int xoff=0; xoff<SDLDISPLAY_SCALE; xoff++) {
|
||||
putpixel(renderer, x+xoff, yoff+y*SDLDISPLAY_SCALE, r, g, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SDLDisplay::drawCharacter(uint8_t mode, uint16_t x, uint16_t y, char c)
|
||||
{
|
||||
int8_t xsize = 8,
|
||||
ysize = 0x07;
|
||||
|
||||
uint16_t offPixel, onPixel;
|
||||
switch (mode) {
|
||||
case M_NORMAL:
|
||||
onPixel = 0xFFFF;
|
||||
offPixel = 0x0010;
|
||||
break;
|
||||
case M_SELECTED:
|
||||
onPixel = 0x0000;
|
||||
offPixel = 0xFFFF;
|
||||
break;
|
||||
case M_DISABLED:
|
||||
default:
|
||||
onPixel = 0x7BEF;
|
||||
offPixel = 0x0000;
|
||||
break;
|
||||
case M_SELECTDISABLED:
|
||||
onPixel = 0x7BEF;
|
||||
offPixel = 0xFFE0;
|
||||
break;
|
||||
case M_PLAIN:
|
||||
onPixel = 0xFFFF;
|
||||
offPixel = 0x0000;
|
||||
break;
|
||||
if ((!use8875) && (x >= ILI9341_WIDTH || y >= ILI9341_HEIGHT)) {
|
||||
printf("err: out of bounds drawing\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// This does not scale when drawing, because drawPixel scales.
|
||||
const unsigned char *ch = asciiToAppleGlyph(c);
|
||||
for (int8_t y_off = 0; y_off <= ysize; y_off++) {
|
||||
for (int8_t x_off = 0; x_off <= xsize; x_off++) {
|
||||
if (*ch & (1 << (x_off))) {
|
||||
drawUIPixel(x + x_off, y + y_off, onPixel);
|
||||
} else {
|
||||
drawUIPixel(x + x_off, y + y_off, offPixel);
|
||||
}
|
||||
}
|
||||
ch++;
|
||||
}
|
||||
}
|
||||
|
||||
void SDLDisplay::drawString(uint8_t mode, uint16_t x, uint16_t y, const char *str)
|
||||
{
|
||||
int8_t xsize = 8; // width of a char in this font
|
||||
|
||||
for (int8_t i=0; i<strlen(str); i++) {
|
||||
drawCharacter(mode, x, y, str[i]);
|
||||
x += xsize; // fixme: any inter-char spacing?
|
||||
if (x >= 320) break; // FIXME constant - and pre-scaling, b/c that's in drawCharacter
|
||||
}
|
||||
videoBuffer[y*(use8875 ? RA8875_WIDTH : ILI9341_WIDTH) + x] = color16To32(color);
|
||||
}
|
||||
|
||||
void SDLDisplay::clrScr(uint8_t coloridx)
|
||||
|
@ -252,98 +325,84 @@ void SDLDisplay::clrScr(uint8_t coloridx)
|
|||
rgbptr = loresPixelColors[coloridx];
|
||||
|
||||
uint32_t packedColor = packColor32(loresPixelColors[coloridx]);
|
||||
|
||||
for (uint16_t y=0; y<SDLDISPLAY_HEIGHT; y++) {
|
||||
for (uint16_t x=0; x<SDLDISPLAY_WIDTH; x++) {
|
||||
videoBuffer[y][x] = packedColor;
|
||||
|
||||
for (uint16_t y=0; y<(use8875 ? RA8875_HEIGHT : ILI9341_HEIGHT); y++) {
|
||||
for (uint16_t x=0; x<(use8875 ? RA8875_WIDTH : ILI9341_WIDTH); x++) {
|
||||
videoBuffer[y*(use8875 ? RA8875_WIDTH : ILI9341_WIDTH) + x] = packedColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This was called with the expectation that it can draw every one of
|
||||
// the 560x192 pixels that could be addressed. If TEENSYDISPLAY_SCALE
|
||||
// is 1, then we have half of that horizontal resolution - so we need
|
||||
// to be creative and blend neighboring pixels together.
|
||||
void SDLDisplay::cachePixel(uint16_t x, uint16_t y, uint8_t color)
|
||||
{
|
||||
#if SDLDISPLAY_SCALE == 1
|
||||
// This is the case where we need to blend together neighboring
|
||||
// pixels, because we don't have enough physical screen resoultion.
|
||||
|
||||
if (x&1) {
|
||||
uint32_t origColor = videoBuffer[y+SCREENINSET_Y][(x>>1)*SDLDISPLAY_SCALE+SCREENINSET_X];
|
||||
uint32_t newColor = packColor32(loresPixelColors[color]);
|
||||
if (g_displayType == m_blackAndWhite) {
|
||||
// There are four reasonable decisions here: if either pixel
|
||||
// *was* on, then it's on; if both pixels *were* on, then it's
|
||||
// on; and if the blended value of the two pixels were on, then
|
||||
// it's on; or if the blended value of the two is above some
|
||||
// certain overall brightness, then it's on. This is the last of
|
||||
// those - where the brightness cutoff is defined in the bios as
|
||||
// g_luminanceCutoff.
|
||||
uint32_t blendedColor = blendPackedColor(origColor, newColor);
|
||||
uint32_t luminance = luminanceFromRGB(unpackRed(blendedColor),
|
||||
unpackGreen(blendedColor),
|
||||
unpackBlue(blendedColor));
|
||||
cacheDoubleWidePixel(x>>1,y,(uint32_t)((luminance >= g_luminanceCutoff) ? 0xFFFFFF : 0x000000));
|
||||
} else {
|
||||
cacheDoubleWidePixel(x>>1,y,(uint32_t)blendPackedColor(origColor, newColor));
|
||||
if (use8875) {
|
||||
for (int yoff=0; yoff<2; yoff++) {
|
||||
videoBuffer[((y*2)+SCREENINSET_8875_Y+yoff)*RA8875_WIDTH +
|
||||
x+SCREENINSET_8875_X] = packColor32(loresPixelColors[color]);
|
||||
}
|
||||
// Else if it's black, we leave whatever was in the other pixel.
|
||||
} else {
|
||||
// The even pixels always draw.
|
||||
cacheDoubleWidePixel(x>>1,y,color);
|
||||
}
|
||||
#else
|
||||
// we have enough resolution to show all the pixels, so just do it
|
||||
x = (x * SDLDISPLAY_SCALE)/2;
|
||||
for (int yoff=0; yoff<SDLDISPLAY_SCALE; yoff++) {
|
||||
for (int xoff=0; xoff<SDLDISPLAY_SCALE; xoff++) {
|
||||
videoBuffer[y*SDLDISPLAY_SCALE+yoff+SCREENINSET_Y][x+xoff+SCREENINSET_X] = packColor32(loresPixelColors[color]);
|
||||
if (x&1) {
|
||||
uint32_t origColor =videoBuffer[(y+SCREENINSET_9341_Y)*ILI9341_WIDTH+(x>>1)+SCREENINSET_9341_X];
|
||||
uint32_t blendedColor = blendColors(origColor,
|
||||
packColor32(loresPixelColors[color]));
|
||||
if (g_displayType == m_blackAndWhite) {
|
||||
uint32_t luminance = luminanceFromRGB((blendedColor & 0xFF0000)>>16,
|
||||
(blendedColor & 0x00FF00)>> 8,
|
||||
(blendedColor & 0x0000FF));
|
||||
cacheDoubleWidePixel(x>>1,y,(uint32_t)((luminance >= g_luminanceCutoff) ? 0xFFFFFF : 0x000000));
|
||||
} else {
|
||||
cacheDoubleWidePixel(x>>1, y, blendedColor);
|
||||
}
|
||||
|
||||
} else {
|
||||
// All of the even pixels get drawn...
|
||||
cacheDoubleWidePixel(x>>1, y, color);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// "DoubleWide" means "please double the X because I'm in low-res width mode"
|
||||
void SDLDisplay::cacheDoubleWidePixel(uint16_t x, uint16_t y, uint8_t color)
|
||||
{
|
||||
for (int yoff=0; yoff<SDLDISPLAY_SCALE; yoff++) {
|
||||
for (int xoff=0; xoff<SDLDISPLAY_SCALE; xoff++) {
|
||||
videoBuffer[y*SDLDISPLAY_SCALE+yoff+SCREENINSET_Y][x*SDLDISPLAY_SCALE+xoff+SCREENINSET_X] = packColor32(loresPixelColors[color]);
|
||||
if (use8875) {
|
||||
for (int yoff=0; yoff<2; yoff++) {
|
||||
for (int xoff=0; xoff<2; xoff++) {
|
||||
videoBuffer[((y*2)+SCREENINSET_8875_Y+yoff)*RA8875_WIDTH +
|
||||
(x*2)+SCREENINSET_8875_X+xoff] = packColor32(loresPixelColors[color]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
videoBuffer[(y+SCREENINSET_9341_Y)*ILI9341_WIDTH + (x) + SCREENINSET_9341_X] = packColor32(loresPixelColors[color]);
|
||||
}
|
||||
}
|
||||
|
||||
void SDLDisplay::cacheDoubleWidePixel(uint16_t x, uint16_t y, uint32_t packedColor)
|
||||
{
|
||||
for (int yoff=0; yoff<SDLDISPLAY_SCALE; yoff++) {
|
||||
for (int xoff=0; xoff<SDLDISPLAY_SCALE; xoff++) {
|
||||
videoBuffer[y*SDLDISPLAY_SCALE+yoff+SCREENINSET_Y][x*SDLDISPLAY_SCALE+xoff+SCREENINSET_X] = packedColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SDLDisplay::cache2DoubleWidePixels(uint16_t x, uint16_t y, uint8_t colorB, uint8_t colorA)
|
||||
{
|
||||
for (int yoff=0; yoff<SDLDISPLAY_SCALE; yoff++) {
|
||||
for (int xoff=0; xoff<SDLDISPLAY_SCALE; xoff++) {
|
||||
videoBuffer[y*SDLDISPLAY_SCALE+yoff+SCREENINSET_Y][x*SDLDISPLAY_SCALE+2*xoff+SCREENINSET_X] = packColor32(loresPixelColors[colorA]);
|
||||
videoBuffer[y*SDLDISPLAY_SCALE+yoff+SCREENINSET_Y][x*SDLDISPLAY_SCALE+1+2*xoff+SCREENINSET_X] = packColor32(loresPixelColors[colorB]);
|
||||
if (use8875) {
|
||||
for (int yoff=0; yoff<2; yoff++) {
|
||||
for (int xoff=0; xoff<2; xoff++) {
|
||||
videoBuffer[((y*2)+SCREENINSET_8875_Y+yoff)*RA8875_WIDTH +
|
||||
(x*2)+SCREENINSET_8875_X+xoff] = packedColor;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
videoBuffer[(y+SCREENINSET_9341_Y)*ILI9341_WIDTH + (x) + SCREENINSET_9341_X] = packedColor;
|
||||
}
|
||||
}
|
||||
|
||||
void SDLDisplay::windowResized(uint32_t w, uint32_t h)
|
||||
{
|
||||
// Preserve the aspect ratio (320/240 == 1.3333)
|
||||
// Preserve the aspect ratio
|
||||
float aspectRatio = (float)w/(float)h;
|
||||
if (aspectRatio != 320.0/240.0) {
|
||||
if (aspectRatio > 320.0/240.0) {
|
||||
h = ((1.f * 240.0) / 320.0) * w;
|
||||
|
||||
float expectedWidth = use8875 ? RA8875_WIDTH : ILI9341_WIDTH;
|
||||
float expectedHeight = use8875 ? RA8875_HEIGHT : ILI9341_HEIGHT;
|
||||
|
||||
if (aspectRatio != ((float)expectedWidth)/((float)expectedHeight)) {
|
||||
if (aspectRatio > ((float)expectedWidth)/((float)expectedHeight)) {
|
||||
h = ((1.f * ((float)expectedHeight)) / ((float)expectedWidth)) * w;
|
||||
} else {
|
||||
w = (320.0/240.0) * h;
|
||||
w = (((float)expectedWidth)/((float)expectedHeight)) * h;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,11 +8,8 @@
|
|||
|
||||
#include "physicaldisplay.h"
|
||||
|
||||
// scale can be 1,2,4. '1' is half-width at the highest resolution
|
||||
// (80-col mode). '2' is full width. '4' is double full width.
|
||||
#define SDLDISPLAY_SCALE 2
|
||||
#define SDLDISPLAY_WIDTH (320*SDLDISPLAY_SCALE)
|
||||
#define SDLDISPLAY_HEIGHT (240*SDLDISPLAY_SCALE)
|
||||
//#define SDL_WIDTH 800
|
||||
//#define SDL_HEIGHT 480
|
||||
|
||||
class SDLDisplay : public PhysicalDisplay {
|
||||
public:
|
||||
|
@ -20,35 +17,45 @@ class SDLDisplay : public PhysicalDisplay {
|
|||
virtual ~SDLDisplay();
|
||||
|
||||
virtual void blit();
|
||||
virtual void blit(AiieRect r);
|
||||
virtual void redraw();
|
||||
|
||||
virtual void flush();
|
||||
|
||||
virtual void drawUIImage(uint8_t imageIdx);
|
||||
virtual void drawDriveActivity(bool drive0, bool drive1);
|
||||
|
||||
virtual void drawImageOfSizeAt(const uint8_t *img, uint16_t sizex, uint16_t sizey, uint16_t wherex, uint16_t wherey);
|
||||
|
||||
virtual void drawPixel(uint16_t x, uint16_t y, uint16_t color);
|
||||
virtual void drawPixel(uint16_t x, uint16_t y, uint8_t r, uint8_t g, uint8_t b);
|
||||
// virtual void drawPixel(uint16_t x, uint16_t y, uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
virtual void drawUIPixel(uint16_t x, uint16_t y, uint16_t color);
|
||||
|
||||
virtual void drawCharacter(uint8_t mode, uint16_t x, uint16_t y, char c);
|
||||
virtual void drawString(uint8_t mode, uint16_t x, uint16_t y, const char *str);
|
||||
virtual void clrScr(uint8_t coloridx);
|
||||
|
||||
virtual void cachePixel(uint16_t x, uint16_t y, uint8_t color);
|
||||
virtual void cacheDoubleWidePixel(uint16_t x, uint16_t y, uint8_t color);
|
||||
void cacheDoubleWidePixel(uint16_t x, uint16_t y, uint32_t packedColor);
|
||||
virtual void cache2DoubleWidePixels(uint16_t x, uint16_t y, uint8_t colorA, uint8_t colorB);
|
||||
|
||||
void windowResized(uint32_t w, uint32_t h);
|
||||
|
||||
private:
|
||||
uint32_t videoBuffer[SDLDISPLAY_HEIGHT][SDLDISPLAY_WIDTH];
|
||||
uint32_t *videoBuffer;
|
||||
|
||||
SDL_Window *screen;
|
||||
SDL_Renderer *renderer;
|
||||
SDL_Texture *buffer;
|
||||
|
||||
uint8_t *shellImage;
|
||||
uint16_t shellWidth, shellHeight;
|
||||
uint8_t *d1OpenImage;
|
||||
uint16_t driveWidth, driveHeight; // assume all the latches are the
|
||||
// same width/height no matter
|
||||
// what position
|
||||
uint8_t *d1ClosedImage;
|
||||
uint8_t *d2OpenImage;
|
||||
uint8_t *d2ClosedImage;
|
||||
uint8_t *appleImage;
|
||||
uint16_t appleImageWidth, appleImageHeight;
|
||||
|
||||
bool driveIndicator[2];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,6 +32,7 @@ uint8_t SDLPaddles::paddle1()
|
|||
|
||||
void SDLPaddles::gotMouseMovement(uint16_t x, uint16_t y)
|
||||
{
|
||||
p0 = ((float)x / (float)SDLDISPLAY_WIDTH) * (float) 255.0;
|
||||
p1 = ((float)y / (float)SDLDISPLAY_HEIGHT) * (float) 255.0;
|
||||
// ***
|
||||
p0 = ((float)x / (float)800) * (float) 255.0;
|
||||
p1 = ((float)y / (float)480) * (float) 255.0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
#include "ILI9341_wrap.h"
|
||||
|
||||
#include "images.h"
|
||||
#include "globals.h"
|
||||
#include "appledisplay.h"
|
||||
#include "palette.h"
|
||||
|
||||
#define _332To565(c) ((((c) & 0xe0) << 8) | (((c) & 0x1c) << 6) | ((c) & 0x03))
|
||||
|
||||
ILI9341_Wrap::ILI9341_Wrap(const uint8_t cs_pin, const uint8_t rst_pin, const uint8_t mosi_pin, const uint8_t sck_pin, const uint8_t miso_pin, const uint8_t dc_pin) : BaseDisplay(cs_pin, rst_pin, mosi_pin, sck_pin, miso_pin, dc_pin)
|
||||
{
|
||||
tft = NULL;
|
||||
frame_buffer = NULL;
|
||||
|
||||
_cs = cs_pin;
|
||||
_dc = dc_pin;
|
||||
_rst = rst_pin;
|
||||
_mosi = mosi_pin;
|
||||
_sck = sck_pin;
|
||||
_miso = miso_pin;
|
||||
}
|
||||
|
||||
ILI9341_Wrap::~ILI9341_Wrap()
|
||||
{
|
||||
if (tft)
|
||||
delete tft;
|
||||
}
|
||||
|
||||
void ILI9341_Wrap::begin(uint32_t spi_clock=30000000u, uint32_t spi_clock_read=2000000)
|
||||
{
|
||||
if (!tft) {
|
||||
tft = new ILI9341_t3n(_cs, _dc, _rst, _mosi, _sck, _miso);
|
||||
tft->begin(spi_clock, spi_clock_read);
|
||||
tft->setRotation(3);
|
||||
}
|
||||
}
|
||||
|
||||
void ILI9341_Wrap::fillWindow(uint8_t coloridx = 0x00)
|
||||
{
|
||||
tft->fillScreen(palette16[coloridx]);
|
||||
}
|
||||
|
||||
void ILI9341_Wrap::setFrameBuffer(uint8_t *frame_buffer)
|
||||
{
|
||||
if (tft) {
|
||||
tft->fillScreen(ILI9341_BLACK);
|
||||
this->frame_buffer = (uint16_t *)frame_buffer;
|
||||
tft->setFrameBuffer((uint16_t *)frame_buffer);
|
||||
tft->useFrameBuffer(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool ILI9341_Wrap::asyncUpdateActive()
|
||||
{
|
||||
return tft ? tft->asyncUpdateActive() : false;
|
||||
}
|
||||
|
||||
bool ILI9341_Wrap::updateScreenAsync(bool update_cont)
|
||||
{
|
||||
return tft ? tft->updateScreenAsync(update_cont) : false;
|
||||
}
|
||||
|
||||
void ILI9341_Wrap::drawPixel(int16_t x, int16_t y, uint16_t color)
|
||||
{
|
||||
if (x>=320 || y>=240)
|
||||
return;
|
||||
|
||||
frame_buffer[y*ILI9341_WIDTH+x] = color;
|
||||
}
|
||||
|
||||
// find the color in the array and return its index
|
||||
static uint8_t reverseColor(uint16_t c)
|
||||
{
|
||||
for (int i=0; i<16; i++) {
|
||||
if (palette16[i] == c)
|
||||
return i;
|
||||
}
|
||||
// didn't find it, return black
|
||||
return c_black;
|
||||
}
|
||||
|
||||
// The 9341 is half the width we need, so this jumps through hoops to
|
||||
// reduce the resolution in a way that's reasonable by blending pixels
|
||||
void ILI9341_Wrap::cacheApplePixel(uint16_t x, uint16_t y, uint8_t coloridx)
|
||||
{
|
||||
if (x>=560 || y>=192)
|
||||
return;
|
||||
|
||||
if (x&1) {
|
||||
uint16_t origColor =frame_buffer[(y+SCREENINSET_9341_Y)*ILI9341_WIDTH+(x>>1)+SCREENINSET_9341_X];
|
||||
uint16_t blendedColor = mix16[reverseColor(origColor)][coloridx];
|
||||
if (g_displayType == m_blackAndWhite) {
|
||||
// There are four reasonable decisions here: if either pixel
|
||||
// *was* on, then it's on; if both pixels *were* on, then it's
|
||||
// on; and if the blended value of the two pixels were on,
|
||||
// then it's on; or if the blended value of the two is above
|
||||
// some certain overall brightness, then it's on. This is the
|
||||
// last of those - where the brightness cutoff is defined in
|
||||
// the bios as g_luminanceCutoff.
|
||||
uint16_t luminance = luminanceFromRGB(_565toR(blendedColor),
|
||||
_565toG(blendedColor),
|
||||
_565toB(blendedColor));
|
||||
cacheDoubleWideApplePixel(x>>1,y,(uint16_t)((luminance >= g_luminanceCutoff) ? c_white : c_black));
|
||||
} else {
|
||||
cacheBlendedPixel(x>>1, y, blendedColor);
|
||||
}
|
||||
} else {
|
||||
// All of the even pixels get drawn...
|
||||
cacheDoubleWideApplePixel(x>>1, y, coloridx);
|
||||
}
|
||||
}
|
||||
|
||||
// This is an internal method that sets a non-standard indexed color
|
||||
void ILI9341_Wrap::cacheBlendedPixel(uint16_t x, uint16_t y, uint16_t c)
|
||||
{
|
||||
if (x>=280 || y>=192)
|
||||
return;
|
||||
|
||||
frame_buffer[(y+SCREENINSET_9341_Y)*ILI9341_WIDTH + (x) + SCREENINSET_9341_X] = c;
|
||||
}
|
||||
|
||||
void ILI9341_Wrap::cacheDoubleWideApplePixel(uint16_t x, uint16_t y, uint8_t coloridx)
|
||||
{
|
||||
if (x>=280 || y>=192)
|
||||
return;
|
||||
|
||||
frame_buffer[(y+SCREENINSET_9341_Y)*ILI9341_WIDTH + (x) + SCREENINSET_9341_X] = palette16[coloridx];
|
||||
}
|
||||
|
||||
uint32_t ILI9341_Wrap::frameCount()
|
||||
{
|
||||
return tft ? tft->frameCount() : 0;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef __ILI9341_WRAP_H
|
||||
#define __ILI9341_WRAP_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
#include <DMAChannel.h>
|
||||
#include <stdint.h>
|
||||
#include <ILI9341_t3n.h>
|
||||
|
||||
#include "basedisplay.h"
|
||||
|
||||
#define ILI9341_WIDTH 320
|
||||
#define ILI9341_HEIGHT 240
|
||||
|
||||
class ILI9341_Wrap : public BaseDisplay {
|
||||
public:
|
||||
ILI9341_Wrap(uint8_t cs_pin, uint8_t rst_pin, uint8_t mosi_pin, uint8_t sck_pin, uint8_t miso_pin, uint8_t dc_pin=255);
|
||||
~ILI9341_Wrap();
|
||||
|
||||
virtual void begin(uint32_t spi_clock=30000000u, uint32_t spi_clock_read=2000000);
|
||||
|
||||
virtual void fillWindow(uint8_t coloridx = 0x00);
|
||||
|
||||
virtual void setFrameBuffer(uint8_t *frame_buffer);
|
||||
|
||||
virtual bool asyncUpdateActive();
|
||||
virtual bool updateScreenAsync(bool update_cont = false);
|
||||
|
||||
virtual void drawPixel(int16_t x, int16_t y, uint16_t color);
|
||||
|
||||
virtual void cacheApplePixel(uint16_t x, uint16_t y, uint8_t coloridx);
|
||||
virtual void cacheDoubleWideApplePixel(uint16_t x, uint16_t y, uint8_t coloridx);
|
||||
|
||||
void cacheBlendedPixel(uint16_t x, uint16_t y, uint16_t color16);
|
||||
|
||||
virtual uint32_t frameCount();
|
||||
|
||||
private:
|
||||
ILI9341_t3n *tft;
|
||||
uint8_t _cs, _dc, _rst, _mosi, _sck, _miso;
|
||||
uint16_t *frame_buffer;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,269 @@
|
|||
#ifndef _RA8875_REGISTERS_H
|
||||
#define _RA8875_REGISTERS_H
|
||||
|
||||
#define CENTER 9998
|
||||
#define ARC_ANGLE_MAX 360
|
||||
#define ARC_ANGLE_OFFSET -90
|
||||
#define ANGLE_OFFSET -90
|
||||
#define RA8875_PWRR 0x01//Power and Display Control Register
|
||||
#define RA8875_PWRR_DISPON 0x80
|
||||
#define RA8875_PWRR_DISPOFF 0x00
|
||||
#define RA8875_PWRR_SLEEP 0x02
|
||||
#define RA8875_PWRR_NORMAL 0x00
|
||||
#define RA8875_PWRR_SOFTRESET 0x01
|
||||
#define RA8875_MRWC 0x02//Memory Read/Write Command
|
||||
#define RA8875_CMDWRITE 0x80
|
||||
#define RA8875_CMDREAD 0xC0
|
||||
#define RA8875_DATAWRITE 0x00
|
||||
#define RA8875_DATAREAD 0x40
|
||||
#define RA8875_STATREG 0x40
|
||||
#define RA8875_PCSR 0x04//Pixel Clock Setting Register
|
||||
#define RA8875_SROC 0x05//Serial Flash/ROM Configuration
|
||||
#define RA8875_SFCLR 0x06//Serial Flash/ROM CLK
|
||||
#define EXTROM_SFCLSPEED 0b00000011// /4 0b00000010 /2
|
||||
#define RA8875_SYSR 0x10//System Configuration Register
|
||||
#define RA8875_HDWR 0x14//LCD Horizontal Display Width Register
|
||||
#define RA8875_HNDFTR 0x15//Horizontal Non-Display Period Fine Tuning Option Register
|
||||
#define RA8875_HNDR 0x16//LCD Horizontal Non-Display Period Register
|
||||
#define RA8875_HSTR 0x17//HSYNC Start Position Register
|
||||
#define RA8875_HPWR 0x18//HSYNC Pulse Width Register
|
||||
#define RA8875_VDHR0 0x19//LCD Vertical Display Height Register 0
|
||||
//#define RA8875_VDHR1 0x1A//LCD Vertical Display Height Register 1
|
||||
#define RA8875_VNDR0 0x1B//LCD Vertical Non-Display Period Register 0
|
||||
//#define RA8875_VNDR1 0x1C//LCD Vertical Non-Display Period Register 1
|
||||
#define RA8875_VSTR0 0x1D//VSYNC Start Position Register 0
|
||||
//#define RA8875_VSTR1 0x1E//VSYNC Start Position Register 1
|
||||
#define RA8875_VPWR 0x1F//VSYNC Pulse Width Register
|
||||
#define RA8875_DPCR 0x20//Display Configuration Register
|
||||
#define RA8875_FNCR0 0x21//Font Control Register 0
|
||||
#define RA8875_FNCR1 0x22//Font Control Register 1
|
||||
#define RA8875_CGSR 0x23//CGRAM Select Register
|
||||
#define RA8875_HOFS0 0x24//Horizontal Scroll Offset Register 0
|
||||
#define RA8875_HOFS1 0x25//Horizontal Scroll Offset Register 1
|
||||
#define RA8875_VOFS0 0x26//Vertical Scroll Offset Register 0
|
||||
#define RA8875_VOFS1 0x27//Vertical Scroll Offset Register 1
|
||||
#define RA8875_FLDR 0x29//Font Line Distance Setting Register
|
||||
#define RA8875_F_CURXL 0x2A//Font Write Cursor Horizontal Position Register 0
|
||||
#define RA8875_F_CURXH 0x2B//Font Write Cursor Horizontal Position Register 1
|
||||
#define RA8875_F_CURYL 0x2C//Font Write Cursor Vertical Position Register 0
|
||||
#define RA8875_F_CURYH 0x2D//Font Write Cursor Vertical Position Register 1
|
||||
#define RA8875_FWTSET 0x2E//Font Write Type Setting Register
|
||||
#define RA8875_SFRSET 0x2F//Serial Font ROM Setting
|
||||
#define RA8875_HSAW0 0x30//Horizontal Start Point 0 of Active Window
|
||||
//#define RA8875_HSAW1 0x31//Horizontal Start Point 1 of Active Window
|
||||
#define RA8875_VSAW0 0x32//Vertical Start Point 0 of Active Window
|
||||
//#define RA8875_VSAW1 0x33//Vertical Start Point 1 of Active Window
|
||||
#define RA8875_HEAW0 0x34//Horizontal End Point 0 of Active Window
|
||||
//#define RA8875_HEAW1 0x35//Horizontal End Point 1 of Active Window
|
||||
#define RA8875_VEAW0 0x36//Vertical End Point of Active Window 0
|
||||
//#define RA8875_VEAW1 0x37//Vertical End Point of Active Window 1
|
||||
#define RA8875_HSSW0 0x38//Horizontal Start Point 0 of Scroll Window
|
||||
//#define RA8875_HSSW1 0x39//Horizontal Start Point 1 of Scroll Window
|
||||
#define RA8875_VSSW0 0x3A//Vertical Start Point 0 of Scroll Window
|
||||
//#define RA8875_VSSW1 0x3B//Vertical Start Point 1 of Scroll Window
|
||||
#define RA8875_HESW0 0x3C//Horizontal End Point 0 of Scroll Window
|
||||
//#define RA8875_HESW1 0x3D//Horizontal End Point 1 of Scroll Window
|
||||
#define RA8875_VESW0 0x3E//Vertical End Point 0 of Scroll Window
|
||||
//#define RA8875_VESW1 0x3F//Vertical End Point 1 of Scroll Window
|
||||
#define RA8875_MWCR0 0x40//Memory Write Control Register 0
|
||||
#define RA8875_MWCR1 0x41//Memory Write Control Register 1
|
||||
#define RA8875_BTCR 0x44//Blink Time Control Register
|
||||
#define RA8875_MRCD 0x45//Memory Read Cursor Direction
|
||||
#define RA8875_CURH0 0x46//Memory Write Cursor Horizontal Position Register 0
|
||||
//#define RA8875_CURH1 0x47//Memory Write Cursor Horizontal Position Register 1
|
||||
#define RA8875_CURV0 0x48//Memory Write Cursor Vertical Position Register 0
|
||||
//#define RA8875_CURV1 0x49//Memory Write Cursor Vertical Position Register 1
|
||||
//#define RA8875_RCURH0 0x4A//Memory Read Cursor Horizontal Position Register 0
|
||||
//#define RA8875_RCURH1 0x4B//Memory Read Cursor Horizontal Position Register 1
|
||||
//#define RA8875_RCURV0 0x4C//Memory Read Cursor Vertical Position Register 0
|
||||
//#define RA8875_RCURV1 0x4D//Memory Read Cursor Vertical Position Register 1
|
||||
#define RA8875_CURHS 0x4E//Font Write Cursor and Memory Write Cursor Horizontal Size Register
|
||||
#define RA8875_CURVS 0x4F//Font Write Cursor Vertical Size Register
|
||||
#define RA8875_BECR0 0x50//BTE Function Control Register 0
|
||||
#define RA8875_BECR1 0x51//BTE Function Control Register 1
|
||||
#define RA8875_LTPR0 0x52//Layer Transparency Register 0
|
||||
#define RA8875_LTPR1 0x53//Layer Transparency Register 1
|
||||
#define RA8875_HSBE0 0x54//Horizontal Source Point 0 of BTE
|
||||
//#define RA8875_HSBE1 0x55//Horizontal Source Point 1 of BTE
|
||||
#define RA8875_VSBE0 0x56//Vertical Source Point 0 of BTE
|
||||
//#define RA8875_VSBE1 0x57//Vertical Source Point 1 of BTE
|
||||
#define RA8875_HDBE0 0x58//Horizontal Destination Point 0 of BTE
|
||||
//#define RA8875_HDBE1 0x59//Horizontal Destination Point 1 of BTE
|
||||
#define RA8875_VDBE0 0x5A//Vertical Destination Point 0 of BTE
|
||||
//#define RA8875_VDBE1 0x5B//Vertical Destination Point 1 of BTE
|
||||
#define RA8875_BEWR0 0x5C//BTE Width Register 0
|
||||
//#define RA8875_BEWR1 0x5D//BTE Width Register 1
|
||||
#define RA8875_BEHR0 0x5E//BTE Height Register 0
|
||||
//#define RA8875_BEHR1 0x5F//BTE Height Register 1
|
||||
#define RA8875_PTNO 0x66//Pattern Set No for BTE
|
||||
#define RA8875_BTEROP_SOURCE 0xC0 //Overwrite dest with source (no mixing) *****THIS IS THE DEFAULT OPTION****
|
||||
#define RA8875_BTEROP_BLACK 0xo0 //all black
|
||||
#define RA8875_BTEROP_WHITE 0xf0 //all white
|
||||
#define RA8875_BTEROP_DEST 0xA0 //destination unchanged
|
||||
#define RA8875_BTEROP_ADD 0xE0 //ADD (brighter)
|
||||
#define RA8875_BTEROP_SUBTRACT 0x20 //SUBTRACT (darker)
|
||||
#define RA8875_BGCR0 0x60//Background Color Register 0 (R)
|
||||
//#define RA8875_BGCR1 0x61//Background Color Register 1 (G)
|
||||
//#define RA8875_BGCR2 0x62//Background Color Register 2 (B)
|
||||
#define RA8875_FGCR0 0x63//Foreground Color Register 0 (R)
|
||||
//#define RA8875_FGCR1 0x64//Foreground Color Register 1 (G)
|
||||
//#define RA8875_FGCR2 0x65//Foreground Color Register 2 (B)
|
||||
#define RA8875_BGTR0 0x67//Background Color Register for Transparent 0 (R)
|
||||
//#define RA8875_BGTR1 0x68//Background Color Register for Transparent 1 (G)
|
||||
//#define RA8875_BGTR2 0x69//Background Color Register for Transparent 2 (B)
|
||||
#define RA8875_TPCR0 0x70//Touch Panel Control Register 0
|
||||
//#define RA8875_TPCR0_ENABLE 0x80
|
||||
//#define RA8875_TPCR0_DISABLE 0x00
|
||||
#define RA8875_TPCR0_WAIT_512CLK 0x00
|
||||
#define RA8875_TPCR0_WAIT_1024CLK 0x10
|
||||
#define RA8875_TPCR0_WAIT_2048CLK 0x20
|
||||
#define RA8875_TPCR0_WAIT_4096CLK 0x30
|
||||
#define RA8875_TPCR0_WAIT_8192CLK 0x40
|
||||
#define RA8875_TPCR0_WAIT_16384CLK 0x50
|
||||
#define RA8875_TPCR0_WAIT_32768CLK 0x60
|
||||
#define RA8875_TPCR0_WAIT_65536CLK 0x70
|
||||
#define RA8875_TPCR0_WAKEENABLE 0x08
|
||||
#define RA8875_TPCR0_WAKEDISABLE 0x00
|
||||
#define RA8875_TPCR0_ADCCLK_DIV1 0x00
|
||||
#define RA8875_TPCR0_ADCCLK_DIV2 0x01
|
||||
#define RA8875_TPCR0_ADCCLK_DIV4 0x02
|
||||
#define RA8875_TPCR0_ADCCLK_DIV8 0x03
|
||||
#define RA8875_TPCR0_ADCCLK_DIV16 0x04
|
||||
#define RA8875_TPCR0_ADCCLK_DIV32 0x05
|
||||
#define RA8875_TPCR0_ADCCLK_DIV64 0x06
|
||||
#define RA8875_TPCR0_ADCCLK_DIV128 0x07
|
||||
#define RA8875_TPCR1 0x71//Touch Panel Control Register 1
|
||||
#define RA8875_TPCR1_AUTO 0x00
|
||||
#define RA8875_TPCR1_MANUAL 0x40
|
||||
#define RA8875_TPCR1_VREFINT 0x00
|
||||
#define RA8875_TPCR1_VREFEXT 0x20
|
||||
#define RA8875_TPCR1_DEBOUNCE 0x04
|
||||
#define RA8875_TPCR1_NODEBOUNCE 0x00
|
||||
#define RA8875_TPCR1_IDLE 0x00
|
||||
#define RA8875_TPCR1_WAIT 0x01
|
||||
#define RA8875_TPCR1_LATCHX 0x02
|
||||
#define RA8875_TPCR1_LATCHY 0x03
|
||||
#define RA8875_TPXH 0x72//Touch Panel X High Byte Data Register
|
||||
#define RA8875_TPYH 0x73//Touch Panel Y High Byte Data Register
|
||||
#define RA8875_TPXYL 0x74//Touch Panel X/Y Low Byte Data Register
|
||||
//#define RA8875_GCHP0 0x80//Graphic Cursor Horizontal Position Register 0
|
||||
//#define RA8875_GCHP1 0x81//Graphic Cursor Horizontal Position Register 1
|
||||
//#define RA8875_GCVP0 0x82//Graphic Cursor Vertical Position Register 0
|
||||
//#define RA8875_GCVP1 0x83//Graphic Cursor Vertical Position Register 0
|
||||
//#define RA8875_GCC0 0x84//Graphic Cursor Color 0
|
||||
//#define RA8875_GCC1 0x85//Graphic Cursor Color 1
|
||||
#define RA8875_PLLC1 0x88//PLL Control Register 1
|
||||
//#define RA8875_PLLC2 0x89//PLL Control Register 2
|
||||
#define RA8875_P1CR 0x8A//PWM1 Control Register
|
||||
#define RA8875_P1DCR 0x8B//PWM1 Duty Cycle Register
|
||||
#define RA8875_P2CR 0x8C//PWM2 Control Register
|
||||
#define RA8875_P2DCR 0x8D//PWM2 Control Register
|
||||
#define RA8875_PxCR_ENABLE 0x80
|
||||
#define RA8875_PxCR_DISABLE 0x00
|
||||
#define RA8875_PxCR_CLKOUT 0x10
|
||||
#define RA8875_PxCR_PWMOUT 0x00
|
||||
#define RA8875_PWM_CLK_DIV1 0x00
|
||||
#define RA8875_PWM_CLK_DIV2 0x01
|
||||
#define RA8875_PWM_CLK_DIV4 0x02
|
||||
#define RA8875_PWM_CLK_DIV8 0x03
|
||||
#define RA8875_PWM_CLK_DIV16 0x04
|
||||
#define RA8875_PWM_CLK_DIV32 0x05
|
||||
#define RA8875_PWM_CLK_DIV64 0x06
|
||||
#define RA8875_PWM_CLK_DIV128 0x07
|
||||
#define RA8875_PWM_CLK_DIV256 0x08
|
||||
#define RA8875_PWM_CLK_DIV512 0x09
|
||||
#define RA8875_PWM_CLK_DIV1024 0x0A
|
||||
#define RA8875_PWM_CLK_DIV2048 0x0B
|
||||
#define RA8875_PWM_CLK_DIV4096 0x0C
|
||||
#define RA8875_PWM_CLK_DIV8192 0x0D
|
||||
#define RA8875_PWM_CLK_DIV16384 0x0E
|
||||
#define RA8875_PWM_CLK_DIV32768 0x0F
|
||||
#define RA8875_MCLR 0x8E//Memory Clear Control Register
|
||||
#define RA8875_DCR 0x90//Draw Line/Circle/Square Control Register
|
||||
#define RA8875_DCR_LINESQUTRI_START 0x80
|
||||
#define RA8875_DCR_LINESQUTRI_STOP 0x00
|
||||
#define RA8875_DCR_LINESQUTRI_STATUS 0x80
|
||||
#define RA8875_DCR_CIRCLE_START 0x40
|
||||
#define RA8875_DCR_CIRCLE_STATUS 0x40
|
||||
#define RA8875_DCR_CIRCLE_STOP 0x00
|
||||
#define RA8875_DCR_FILL 0x20
|
||||
#define RA8875_DCR_NOFILL 0x00
|
||||
#define RA8875_DCR_DRAWLINE 0x00
|
||||
#define RA8875_DCR_DRAWTRIANGLE 0x01
|
||||
#define RA8875_DCR_DRAWSQUARE 0x10
|
||||
#define RA8875_DLHSR0 0x91//Draw Line/Square Horizontal Start Address Register0
|
||||
//#define RA8875_DLHSR1 0x92//Draw Line/Square Horizontal Start Address Register1
|
||||
#define RA8875_DLVSR0 0x93//Draw Line/Square Vertical Start Address Register0
|
||||
//#define RA8875_DLVSR1 0x94//Draw Line/Square Vertical Start Address Register1
|
||||
#define RA8875_DLHER0 0x95//Draw Line/Square Horizontal End Address Register0
|
||||
//#define RA8875_DLHER1 0x96//Draw Line/Square Horizontal End Address Register1
|
||||
#define RA8875_DLVER0 0x97//Draw Line/Square Vertical End Address Register0
|
||||
//#define RA8875_DLVER1 0x98//Draw Line/Square Vertical End Address Register0
|
||||
#define RA8875_DCHR0 0x99//Draw Circle Center Horizontal Address Register0
|
||||
//#define RA8875_DCHR1 0x9A//Draw Circle Center Horizontal Address Register1
|
||||
#define RA8875_DCVR0 0x9B//Draw Circle Center Vertical Address Register0
|
||||
//#define RA8875_DCVR1 0x9C//Draw Circle Center Vertical Address Register1
|
||||
#define RA8875_DCRR 0x9D//Draw Circle Radius Register
|
||||
#define RA8875_ELLIPSE 0xA0//Draw Ellipse/Ellipse Curve/Circle Square Control Register
|
||||
#define RA8875_ELLIPSE_STATUS 0x80
|
||||
#define RA8875_ELL_A0 0xA1//Draw Ellipse/Circle Square Long axis Setting Register0
|
||||
//#define RA8875_ELL_A1 0xA2//Draw Ellipse/Circle Square Long axis Setting Register1
|
||||
#define RA8875_ELL_B0 0xA3//Draw Ellipse/Circle Square Short axis Setting Register0
|
||||
//#define RA8875_ELL_B1 0xA4//Draw Ellipse/Circle Square Short axis Setting Register1
|
||||
#define RA8875_DEHR0 0xA5//Draw Ellipse/Circle Square Center Horizontal Address Register0
|
||||
//#define RA8875_DEHR1 0xA6//Draw Ellipse/Circle Square Center Horizontal Address Register1
|
||||
#define RA8875_DEVR0 0xA7//Draw Ellipse/Circle Square Center Vertical Address Register0
|
||||
//#define RA8875_DEVR1 0xA8//Draw Ellipse/Circle Square Center Vertical Address Register1
|
||||
#define RA8875_DTPH0 0xA9//Draw Triangle Point 2 Horizontal Address Register0
|
||||
//#define RA8875_DTPH1 0xAA//Draw Triangle Point 2 Horizontal Address Register1
|
||||
#define RA8875_DTPV0 0xAB//Draw Triangle Point 2 Vertical Address Register0
|
||||
//#define RA8875_DTPV1 0xAC//Draw Triangle Point 2 Vertical Address Register1
|
||||
#define RA8875_SSAR0 0xB0//Source Starting Address REG 0
|
||||
//#define RA8875_SSAR1 0xB1//Source Starting Address REG 1
|
||||
//#define RA8875_SSAR2 0xB2//Source Starting Address REG 2
|
||||
//#define RA8875_???? 0xB3//???????????
|
||||
#define RA8875_DTNR0 0xB4//Block Width REG 0(BWR0) / DMA Transfer Number REG 0
|
||||
#define RA8875_BWR1 0xB5//Block Width REG 1
|
||||
#define RA8875_DTNR1 0xB6//Block Height REG 0(BHR0) /DMA Transfer Number REG 1
|
||||
#define RA8875_BHR1 0xB7//Block Height REG 1
|
||||
#define RA8875_DTNR2 0xB8//Source Picture Width REG 0(SPWR0) / DMA Transfer Number REG 2
|
||||
#define RA8875_SPWR1 0xB9//Source Picture Width REG 1
|
||||
#define RA8875_DMACR 0xBF//DMA Configuration REG
|
||||
#define RA8875_GPIOX 0xC7
|
||||
#define RA8875_KSCR1 0xC0 //Key-Scan Control Register 1 (KSCR1)
|
||||
#define RA8875_KSCR2 0xC1 //Key-Scan Controller Register 2 (KSCR2)
|
||||
#define RA8875_KSDR0 0xC2 //Key-Scan Data Register (KSDR0)
|
||||
#define RA8875_KSDR1 0xC3 //Key-Scan Data Register (KSDR1)
|
||||
#define RA8875_KSDR2 0xC4 //Key-Scan Data Register (KSDR2)
|
||||
#define RA8875_INTC1 0xF0//Interrupt Control Register1
|
||||
#define RA8875_INTC2 0xF1//Interrupt Control Register2
|
||||
#define RA8875_INTCx_KEY 0x10
|
||||
#define RA8875_INTCx_DMA 0x08
|
||||
#define RA8875_INTCx_TP 0x04
|
||||
#define RA8875_INTCx_BTE 0x02
|
||||
#define RA8875_ENABLE_INT_TP ((uint8_t)(1<<2))
|
||||
#define RA8875_DISABLE_INT_TP ((uint8_t)(0<<2))
|
||||
#define TP_ENABLE ((uint8_t)(1<<7))
|
||||
#define TP_DISABLE ((uint8_t)(0<<7))
|
||||
#define TP_MODE_AUTO ((uint8_t)(0<<6))
|
||||
#define TP_MODE_MANUAL ((uint8_t)(1<<6))
|
||||
#define TP_DEBOUNCE_OFF ((uint8_t)(0<<2))
|
||||
#define TP_DEBOUNCE_ON ((uint8_t)(1<<2))
|
||||
#define TP_ADC_CLKDIV_1 0
|
||||
#define TP_ADC_CLKDIV_2 1
|
||||
#define TP_ADC_CLKDIV_4 2
|
||||
#define TP_ADC_CLKDIV_8 3
|
||||
#define TP_ADC_CLKDIV_16 4
|
||||
#define TP_ADC_CLKDIV_32 5
|
||||
#define TP_ADC_CLKDIV_64 6
|
||||
#define TP_ADC_CLKDIV_128 7
|
||||
#define TP_ADC_SAMPLE_512_CLKS ((uint8_t)(0<<4))
|
||||
#define TP_ADC_SAMPLE_1024_CLKS ((uint8_t)(1<<4))
|
||||
#define TP_ADC_SAMPLE_2048_CLKS ((uint8_t)(2<<4))
|
||||
#define TP_ADC_SAMPLE_4096_CLKS ((uint8_t)(3<<4))
|
||||
#define TP_ADC_SAMPLE_8192_CLKS ((uint8_t)(4<<4))
|
||||
#define TP_ADC_SAMPLE_16384_CLKS ((uint8_t)(5<<4))
|
||||
#define TP_ADC_SAMPLE_32768_CLKS ((uint8_t)(6<<4))
|
||||
#define TP_ADC_SAMPLE_65536_CLKS ((uint8_t)(7<<4))
|
||||
|
||||
#endif
|
|
@ -0,0 +1,581 @@
|
|||
#include "RA8875_t4.h"
|
||||
#include "RA8875_registers.h"
|
||||
|
||||
#include "images.h"
|
||||
|
||||
#include "palette.h"
|
||||
|
||||
// Discussion about DMA channels: http://forum.pjrc.com/threads/25778-Could-there-be-something-like-an-ISR-template-function/page3
|
||||
// Thread discussing the way to get started: https://forum.pjrc.com/threads/63353-Teensy-4-1-How-to-start-using-DMA
|
||||
// Thread of someone writing an LCD interface: https://forum.pjrc.com/threads/67247-Teensy-4-0-DMA-SPI
|
||||
// And these libraries use it:
|
||||
// https://github.com/PaulStoffregen/Audio
|
||||
// https://github.com/PaulStoffregen/OctoWS2811
|
||||
// https://github.com/pedvide/ADC
|
||||
// https://github.com/duff2013/SerialEvent
|
||||
// https://github.com/pixelmatix/SmartMatrix
|
||||
// https://github.com/crteensy/DmaSpi <-- DmaSpi has adopted this scheme
|
||||
//
|
||||
|
||||
/* The ST7735 and ILI9341 have both been modified in the Teensyduino
|
||||
* distribution to use DMA + SPI the way that I want to do this here.
|
||||
* The major differences here:
|
||||
* - Both the 7735 and 9341 use 16-bit transfers. Since this has a
|
||||
* substantially larger framebuffer that doesn't fit in the DMAMEM
|
||||
* region, that won't work -- so I'm using 8-bpp mode.
|
||||
* - Both the ILI9341 and ST7735 have a D/C pin to tell the display
|
||||
* if the data being sent is a command or is data. The 8875 does
|
||||
* not have a D/C pin.
|
||||
* - Both the 7735 and 9341 drivers have a lot of #ifdef overhead
|
||||
* to support multiple different Teensys. I'm targeting the 4.1
|
||||
* so I'm not including any of that abstraction.
|
||||
* - The RA8875 driver supports multiple different pixel-size
|
||||
* displays (and vendors' interfaces). Aiie only supports 800x480
|
||||
* using the Adafruit RA8875 display module.
|
||||
* - Each dmasettings looks like it can address 32767 bytes of data,
|
||||
* so while the 320*240 16-bit structure needs 3 structs (well,
|
||||
* 2.34 structs) the 800*480 8-bit structure needs 12 structs.
|
||||
*
|
||||
*
|
||||
* The initialization sets us to 8bpp color mode, so that 800*480 fits
|
||||
* within 512k of RAM (800*480 bytes = 375k; if this were 16bpp, then
|
||||
* it would overflow by 238k.) This is important because, if I
|
||||
* understand it rightly, only one of the 512k banks on the Teensy is
|
||||
* coupled to DMA. (The other bank of memory is tightly coupled to the
|
||||
* processor for faster access.) It's possible to further reduce our
|
||||
* memory footprint if necessary by just caching the Apple's display
|
||||
* size of 560x240 (reducing it to about 132k) and initializing the
|
||||
* display with a "display window" for that area of the screen,
|
||||
* turning off DMA and drawing outside the window when necessary (to
|
||||
* update a drive indicator, debug message, or the UI outline itself).
|
||||
*
|
||||
* The core drawing operation uses the RA8875's MRWC command to send
|
||||
* data in a transaction, driven by the DMA layer. It will do this:
|
||||
* start
|
||||
* RA8875_CMDWRITE
|
||||
* RA8875_MRWC
|
||||
* end
|
||||
* start
|
||||
* RA8875_DATAWRITE
|
||||
* <all the data>
|
||||
* end
|
||||
*
|
||||
* It's unclear to me whether or not we'll have to end and restart
|
||||
* after every frame, but I'll find out as it's built...
|
||||
*
|
||||
* The one abstraction I did leave in here is which SPI pins are being
|
||||
* used. This still supports moving to any of the three SPI busses.
|
||||
*
|
||||
* WIP: using the LED and Serial to debug why interrupts haven't been
|
||||
* firing the way I expected. I think it may be because I didn't have a
|
||||
* transaction running.
|
||||
* ... no, that didn't seem to solve the problem.
|
||||
*
|
||||
* I don't know if the way I'm maybeUpdateTCR-ing with
|
||||
* LPSPI_TCR_PCS(3) is correct or not -- I haven't fully comprehended
|
||||
* what the code in 9341/7735 are doing there, because it's combined
|
||||
* with the D/C pin functionality. But LPSPI_TCR_PCS refers to
|
||||
* the SPI peripheral chip select: 00 = LPSPI_PCS[0]; 01 = 1; etc.
|
||||
* From what I see in the original maybeUpdateTCR method, it's using
|
||||
* LPSPI_TCR_PCS(3) as a CARRIER of the expected state of the _dc
|
||||
* pin. It is masked back out before setting TCR. So I think the
|
||||
* right thing to do here is completely remove all of the LPSPI_TCR_PCS
|
||||
* bits. ... but it still isn't getting to an interrupt state.
|
||||
*
|
||||
* Some pages I've been reading:
|
||||
* https://forum.pjrc.com/threads/57280-RA8875-from-Buydisplay/page9?highlight=lpspi_tcr_pcs (pg9)
|
||||
* https://www.displayfuture.com/Display/datasheet/controller/ST7735.pdf
|
||||
* https://github.com/ElectroTechnique/TSynth-for-Teensy3.6/blob/master/ST7735_t3.cpp
|
||||
* https://github-wiki-see.page/m/TeensyUser/doc/wiki/Memory-Mapping
|
||||
*/
|
||||
|
||||
// Static DMA objects that we need in RAM1
|
||||
DMASetting _dmasettings[12];
|
||||
DMAChannel _dmatx;
|
||||
|
||||
// at 8bpp, each pixel is 1 byte
|
||||
#define COUNT_PIXELS_WRITE (RA8875_WIDTH * RA8875_HEIGHT)
|
||||
|
||||
#define TCR_MASK ( LPSPI_TCR_FRAMESZ(31) | LPSPI_TCR_CONT | LPSPI_TCR_RXMSK )
|
||||
#define _565toR(c) ( ((c) & 0xF800) >> 8 )
|
||||
#define _565toG(c) ( ((c) & 0x07E0) >> 3 )
|
||||
#define _565toB(c) ( ((c) & 0x001F) << 3 )
|
||||
#define _565To332(c) ((((c) & 0xe000) >> 8) | (((c) & 0x700) >> 6) | (((c) & 0x18) >> 3))
|
||||
|
||||
// 3 of these, one for each of the 3 busses, so that 3 separate
|
||||
// displays could be driven. FIXME: I don't really need all 3 in this
|
||||
// application, so this can be pared down.
|
||||
static RA8875_t4 *_dmaActiveDisplay = NULL;
|
||||
|
||||
RA8875_t4::RA8875_t4(uint8_t cs_pin, uint8_t rst_pin, uint8_t mosi_pin, uint8_t sck_pin, uint8_t miso_pin, uint8_t dc_pin) : BaseDisplay(cs_pin, rst_pin, mosi_pin, sck_pin, miso_pin, dc_pin)
|
||||
{
|
||||
_mosi = mosi_pin;
|
||||
_miso = miso_pin;
|
||||
_cs = cs_pin;
|
||||
_rst = rst_pin;
|
||||
_sck = sck_pin;
|
||||
|
||||
_pspi = NULL;
|
||||
_pfbtft = NULL;
|
||||
_dma_state = 0;
|
||||
_dma_frame_count = 0;
|
||||
_dmaActiveDisplay = NULL;
|
||||
}
|
||||
|
||||
RA8875_t4::~RA8875_t4()
|
||||
{
|
||||
}
|
||||
|
||||
void RA8875_t4::begin(uint32_t spi_clock, uint32_t spi_clock_read)
|
||||
{
|
||||
Serial.print(" starting RA8875 @ ");
|
||||
Serial.println(spi_clock);
|
||||
_spi_clock = spi_clock;
|
||||
_spi_clock_read = spi_clock_read; // FIXME not used at the moment, not sure we need it yet
|
||||
_clock = 4000000UL; // start at low speed
|
||||
|
||||
// figure out which SPI bus we're using
|
||||
if (SPI.pinIsMOSI(_mosi) && ((_miso == 0xff) || SPI.pinIsMISO(_miso)) && SPI.pinIsSCK(_sck)) {
|
||||
_pspi = &SPI;
|
||||
_pimxrt_spi = &IMXRT_LPSPI4_S;
|
||||
} else if (SPI1.pinIsMOSI(_mosi) && ((_miso == 0xff) || SPI1.pinIsMISO(_miso)) && SPI1.pinIsSCK(_sck)) {
|
||||
_pspi = &SPI1;
|
||||
_pimxrt_spi = &IMXRT_LPSPI3_S;
|
||||
} else if (SPI2.pinIsMOSI(_mosi) && ((_miso == 0xff) || SPI2.pinIsMISO(_miso)) && SPI2.pinIsSCK(_sck)) {
|
||||
_pspi = &SPI2;
|
||||
_pimxrt_spi = &IMXRT_LPSPI1_S;
|
||||
} else {
|
||||
Serial.println("Pins given are not valid SPI bus pins");
|
||||
return;
|
||||
}
|
||||
|
||||
_pspi->setMOSI(_mosi);
|
||||
_pspi->setSCK(_sck);
|
||||
if (_miso != 0xff) _pspi->setMISO(_miso);
|
||||
uint32_t *pa = (uint32_t *)_pspi;
|
||||
_spi_hardware = (SPIClass::SPI_Hardware_t *)pa[1];
|
||||
|
||||
_pspi->begin();
|
||||
|
||||
pinMode(_cs, OUTPUT);
|
||||
digitalWriteFast(_cs, HIGH);
|
||||
|
||||
_spi_tcr_current = _pimxrt_spi->TCR; // get the current TCR value
|
||||
|
||||
maybeUpdateTCR(LPSPI_TCR_FRAMESZ(7));
|
||||
|
||||
_initializeTFT();
|
||||
}
|
||||
|
||||
void RA8875_t4::_initializeTFT()
|
||||
{
|
||||
// toggle RST low to reset
|
||||
if (_rst < 255) {
|
||||
pinMode(_rst, OUTPUT);
|
||||
digitalWriteFast(_rst, HIGH);
|
||||
delay(10);
|
||||
digitalWriteFast(_rst, LOW);
|
||||
delay(220);
|
||||
digitalWriteFast(_rst, HIGH);
|
||||
delay(300);
|
||||
} else {
|
||||
// Try a soft reset
|
||||
writeCommand(RA8875_PWRR);
|
||||
_writeData(RA8875_PWRR_SOFTRESET);
|
||||
delay(20);
|
||||
_writeData(RA8875_PWRR_NORMAL);
|
||||
delay(200);
|
||||
}
|
||||
|
||||
// Set the sysclock
|
||||
_writeRegister(RA8875_PLLC1, 0x07); // same as default value: %0000 0111 == pre /=1; input /=7
|
||||
delay(1);
|
||||
_writeRegister(RA8875_PLLC1+1, 0x03); // same as default value: %0000 0011 == output /8
|
||||
delay(1);
|
||||
_writeRegister(RA8875_PCSR, 0x81); // pixel clock setting register: %1000 0001 == PDAT at PCLK falling edge; PCLK period is 2* system clock period
|
||||
delay(1);
|
||||
|
||||
// colorspace
|
||||
_writeRegister(RA8875_SYSR, 0x00); // 8-bit (0x0C == 16-bit)
|
||||
|
||||
_writeRegister(RA8875_HDWR, 0x63); // LCD horizontal display width == (v+1)*8
|
||||
_writeRegister(RA8875_HNDFTR, 0x00); // Horizontal non-display period fine tuning
|
||||
_writeRegister(RA8875_HNDR, 0x03); // LCD Horizontal non-display period register; period (in pixels) = (v+1)*8 + HNDFTR+2 == 32
|
||||
_writeRegister(RA8875_HSTR, 0x03); // HSYNC start position register; start position (in pixels) = (v+1)*8 == 24
|
||||
_writeRegister(RA8875_HPWR, 0x0B); // HSYNC pulse width register; %0000 1011 == HSYNC low active, hsync pulse width = ((v&32)+1)*8 = 88
|
||||
_writeRegister(RA8875_VDHR0, 0xDF); // LCD Vertical display height register 0 (low byte of height, where height = this value + 1)
|
||||
_writeRegister(RA8875_VDHR0+1, 0x01); // LCD Vertical display height register 1 (high byte of height)
|
||||
_writeRegister(RA8875_VNDR0, 0x1F); // LCD vertical non-display period register 0 (low byte of non-display period in lines, where period=(VNDR+1) == 32)
|
||||
_writeRegister(RA8875_VNDR0+1, 0x00); // LCD vertical non-display period register 1 (high byte of non-display period in lines)
|
||||
_writeRegister(RA8875_VSTR0, 0x16); // VSYNC start position register 0; low byte, where start pos(line) = (VSTR+1) == 23
|
||||
_writeRegister(RA8875_VSTR0+1, 0x00); // VSYNC start position register 1; high byte
|
||||
_writeRegister(RA8875_VPWR, 0x01); // VSYNC pulse width register; %0000 0001 == low active, pulse width (in lines) = (v&0x7F)+1 == 2
|
||||
|
||||
// Set the entire screen as the active window
|
||||
_writeRegister(RA8875_HSAW0, 0x00); // horizontal start point of active window
|
||||
_writeRegister(RA8875_HSAW0+1, 0x00);
|
||||
_writeRegister(RA8875_HEAW0, (RA8875_WIDTH-1) & 0xFF);
|
||||
_writeRegister(RA8875_HEAW0+1, (RA8875_WIDTH-1) >> 8); // horizontal end point of active window
|
||||
_writeRegister(RA8875_VSAW0, 0x00); // vertical start point of active window
|
||||
_writeRegister(RA8875_VSAW0+1, 0x00);
|
||||
_writeRegister(RA8875_VEAW0, (RA8875_HEIGHT-1) & 0xFF); // vertical end point of active window
|
||||
_writeRegister(RA8875_VEAW0+1, (RA8875_HEIGHT-1) >> 8);
|
||||
|
||||
delay(100);
|
||||
|
||||
// clear memory
|
||||
uint8_t temp;
|
||||
temp = _readRegister(RA8875_MCLR);
|
||||
temp |= (1<<7);
|
||||
_writeData(temp);
|
||||
_waitBusy(0x80);
|
||||
|
||||
delay(1);
|
||||
|
||||
// Update the sysclock. 300MHz Fpll; 150MHz sysclk; 18.75 MHz pixel
|
||||
// clock. That's the fastest that seems to reliably work for me. It
|
||||
// also allows a SPI bus transfer at just under 80MHz (literally
|
||||
// 79.999... there must be a constant somewhere that's breaking the
|
||||
// SPI module at 80, or a Teensy 4.1 bus limit, or ... ?)
|
||||
_writeRegister(RA8875_PLLC1, 0x0E);
|
||||
delay(1);
|
||||
_writeRegister(RA8875_PLLC1+1, 0x01);
|
||||
delay(1);
|
||||
_writeRegister(RA8875_PCSR, 0x82);
|
||||
delay(1);
|
||||
|
||||
_clock = _spi_clock; // speed up to full speed now
|
||||
|
||||
delay(10);
|
||||
|
||||
// turn on the display
|
||||
_writeRegister(RA8875_PWRR, RA8875_PWRR_NORMAL | RA8875_PWRR_DISPON);
|
||||
delay(1);
|
||||
fillWindow(); // defaults to black
|
||||
|
||||
// turn on backlight
|
||||
_writeRegister(RA8875_P1CR, (RA8875_PxCR_ENABLE | (RA8875_PWM_CLK_DIV2048 & 0xF)));
|
||||
_writeRegister(RA8875_P1DCR, 255); // brightness
|
||||
|
||||
// set graphics mode & default memory write order/behavior
|
||||
_writeRegister(RA8875_MWCR0, 0x00);
|
||||
|
||||
// *** rotation?
|
||||
|
||||
// Not sure we have to do this a second time, but set active window...
|
||||
_writeRegister(RA8875_HSAW0, 0x00); // horizontal start point of active window
|
||||
_writeRegister(RA8875_HSAW0+1, 0x00);
|
||||
_writeRegister(RA8875_HEAW0, (RA8875_WIDTH-1) & 0xFF);
|
||||
_writeRegister(RA8875_HEAW0+1, (RA8875_WIDTH-1) >> 8); // horizontal end point of active window
|
||||
_writeRegister(RA8875_VSAW0, 0x00); // vertical start point of active window
|
||||
_writeRegister(RA8875_VSAW0+1, 0x00);
|
||||
_writeRegister(RA8875_VEAW0, (RA8875_HEIGHT-1) & 0xFF); // vertical end point of active window
|
||||
_writeRegister(RA8875_VEAW0+1, (RA8875_HEIGHT-1) >> 8);
|
||||
|
||||
// set foreground color
|
||||
_writeRegister(RA8875_FGCR0, 0);
|
||||
_writeRegister(RA8875_FGCR0+1, 0);
|
||||
_writeRegister(RA8875_FGCR0+2, 0);
|
||||
// set background color
|
||||
_writeRegister(RA8875_BGCR0, 0);
|
||||
_writeRegister(RA8875_BGCR0+1, 0);
|
||||
_writeRegister(RA8875_BGCR0+2, 0);
|
||||
|
||||
// _writeRegister(RA8875_FNCR1, 0); // probably not necessary since we're not using built-in fonts
|
||||
// setCursor(0,0);
|
||||
|
||||
_writeRegister(RA8875_GPIOX, true); // turn on backlight
|
||||
}
|
||||
|
||||
void RA8875_t4::setFrameBuffer(uint8_t *frame_buffer)
|
||||
{
|
||||
Serial.print("fb 0x");
|
||||
Serial.println((uint32_t)frame_buffer, HEX);
|
||||
_pfbtft = frame_buffer;
|
||||
_dma_state &= ~RA8875_DMA_INIT;
|
||||
}
|
||||
|
||||
bool RA8875_t4::asyncUpdateActive()
|
||||
{
|
||||
return (_dma_state & RA8875_DMA_ACTIVE);
|
||||
}
|
||||
|
||||
void RA8875_t4::initDMASettings()
|
||||
{
|
||||
if (_dma_state & RA8875_DMA_INIT)
|
||||
return;
|
||||
|
||||
uint8_t dmaTXevent = _spi_hardware->tx_dma_channel;
|
||||
|
||||
// Each DMA structure can only track 32767 words written (where a
|
||||
// word here is 8 bits). So we need 12 of these to cover the whole
|
||||
// set of 800*480 display data. And we're assuming that they are
|
||||
// evenly divisible, and that the DMA engine won't care if the
|
||||
// data isn't all aligned to 2^15 boundaries.
|
||||
uint16_t pixelsWrittenPerDMAreq = COUNT_PIXELS_WRITE / 12;
|
||||
|
||||
if (_dma_state & RA8875_DMA_EVER_INIT) {
|
||||
// Just quickly reset the pointers and sizes
|
||||
for (int i=0; i<12; i++) {
|
||||
_dmasettings[i].sourceBuffer(&_pfbtft[pixelsWrittenPerDMAreq*i], pixelsWrittenPerDMAreq);
|
||||
}
|
||||
} else {
|
||||
for (int i=0; i<12; i++) {
|
||||
_dmasettings[i].sourceBuffer(&_pfbtft[pixelsWrittenPerDMAreq*i], pixelsWrittenPerDMAreq);
|
||||
_dmasettings[i].destination(_pimxrt_spi->TDR); // DMA sends data to LPSPI's transmit data register
|
||||
_dmasettings[i].TCD->ATTR_DST = 0; // 8-bit destination size (%000)
|
||||
_dmasettings[i].replaceSettingsOnCompletion(_dmasettings[(i+1)%12]);
|
||||
}
|
||||
// "half done" for 12 is at the end of index 5, so we don't have to set up interruptAtHalf()
|
||||
// but we do have to change the way we deal with sub-frame counting. If we need it. I don't
|
||||
// think we do, so I'm leaving this here as a comment for now...
|
||||
// _dmasettings[5].interruptAtCompletion();
|
||||
_dmasettings[11].interruptAtCompletion();
|
||||
|
||||
// Not sure we need this...
|
||||
//_dmasettings[11].TCD->CSR &= ~(DMA_TCD_CSR_DREQ); // DMA_TCDn_CSR[3] -- If this flag is set, the eDMA hardware automatically clears the corresponding ERQ bit when the current major iteration count reaches zero.
|
||||
|
||||
_dmatx = _dmasettings[0];
|
||||
_dmatx.begin(true);
|
||||
_dmatx.triggerAtHardwareEvent(dmaTXevent);
|
||||
_dmatx.attachInterrupt(dmaInterrupt);
|
||||
_dma_state = RA8875_DMA_INIT | RA8875_DMA_EVER_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
bool RA8875_t4::updateScreenAsync(bool update_cont)
|
||||
{
|
||||
if (!_pfbtft) return false;
|
||||
|
||||
// Half of main ram has a 32k cache. This tells it to flush the cache if necessary.
|
||||
if ((uint32_t)_pfbtft >= 0x20200000u) arm_dcache_flush(_pfbtft, RA8875_WIDTH*RA8875_HEIGHT);
|
||||
|
||||
if (_dma_state & RA8875_DMA_ACTIVE) {
|
||||
return false;
|
||||
}
|
||||
initDMASettings();
|
||||
|
||||
// Don't need to reset the window b/c we never change it; but set the X/Y cursor back to the origin
|
||||
_writeRegister(RA8875_CURV0, 0);
|
||||
_writeRegister(RA8875_CURV0+1, 0);
|
||||
_writeRegister(RA8875_CURH0, 0);
|
||||
_writeRegister(RA8875_CURH0+1, 0);
|
||||
|
||||
// Start it sending data
|
||||
writeCommand(RA8875_MRWC);
|
||||
_startSend();
|
||||
_pspi->transfer(RA8875_DATAWRITE);
|
||||
|
||||
_spi_fcr_save = _pimxrt_spi->FCR; // FIFO Control Register
|
||||
_pimxrt_spi->FCR=0; // turn off FIFO watermarks
|
||||
|
||||
// Set transmit command register: disable RX ("mask out RX"), enable
|
||||
// TX from FIFO (b/c it's not masked out), and 8-bit data transfers
|
||||
// (7+1).
|
||||
maybeUpdateTCR(LPSPI_TCR_FRAMESZ(7) | LPSPI_TCR_RXMSK /*| LPSPI_TCR_CONT*/);
|
||||
// Set up the DMA Enable Register to enable transmit DMA (and not receive DMA)
|
||||
_pimxrt_spi->DER = LPSPI_DER_TDDE;
|
||||
_pimxrt_spi->SR = 0x3f00; // Clear error flags (these are w1c flags - "write 1 to clear")
|
||||
_dmatx.triggerAtHardwareEvent( _spi_hardware->tx_dma_channel );
|
||||
_dmatx = _dmasettings[0];
|
||||
|
||||
_dma_frame_count = 0;
|
||||
_dmaActiveDisplay = this;
|
||||
|
||||
_dmatx.begin(false);
|
||||
_dmatx.enable();
|
||||
if (update_cont) {
|
||||
_dma_state |= RA8875_DMA_CONT;
|
||||
} else {
|
||||
_dmasettings[11].disableOnCompletion();
|
||||
_dma_state &= ~RA8875_DMA_CONT;
|
||||
}
|
||||
_dma_state |= RA8875_DMA_ACTIVE;
|
||||
|
||||
// Make sure the dma settings are flushed. Otherwise bad things happen.
|
||||
if ((uint32_t)_dmasettings >= 0x20200000u)
|
||||
arm_dcache_flush(_dmasettings, sizeof(DMASetting)*12); // FIXME constant
|
||||
return true;
|
||||
}
|
||||
|
||||
void RA8875_t4::fillWindow(uint8_t coloridx)
|
||||
{
|
||||
if (!_pfbtft)
|
||||
return;
|
||||
|
||||
// Reduce color to 8 bit
|
||||
uint8_t c8 = palette8[coloridx];
|
||||
memset(_pfbtft, c8, RA8875_WIDTH*RA8875_HEIGHT);
|
||||
}
|
||||
|
||||
void RA8875_t4::drawPixel(int16_t x, int16_t y, uint16_t color)
|
||||
{
|
||||
if (x>=800 || y>=480) {
|
||||
Serial.print("^ ");
|
||||
Serial.print(x);
|
||||
Serial.print(" ");
|
||||
Serial.println(y);
|
||||
return;
|
||||
}
|
||||
|
||||
_pfbtft[y*RA8875_WIDTH+x] = _565To332(color);
|
||||
}
|
||||
|
||||
void RA8875_t4::cacheApplePixel(uint16_t x, uint16_t y, uint8_t coloridx)
|
||||
{
|
||||
if (x>=560 || y>=192) {
|
||||
Serial.print("! ");
|
||||
Serial.print(x);
|
||||
Serial.print(" ");
|
||||
Serial.println(y);
|
||||
return;
|
||||
}
|
||||
|
||||
// The 8875 display doubles vertically
|
||||
uint c8 = palette8[coloridx];
|
||||
for (int yoff=0; yoff<2; yoff++) {
|
||||
_pfbtft[((y*2)+SCREENINSET_8875_Y+yoff) * RA8875_WIDTH +x+SCREENINSET_8875_X] = c8;
|
||||
}
|
||||
}
|
||||
|
||||
void RA8875_t4::cacheDoubleWideApplePixel(uint16_t x, uint16_t y, uint8_t coloridx)
|
||||
{
|
||||
if (x>=280 || y>=192) {
|
||||
Serial.println("@");
|
||||
return;
|
||||
}
|
||||
|
||||
// The RA8875 doubles Apple's pixels.
|
||||
for (int yoff=0; yoff<2; yoff++) {
|
||||
for (int xoff=0; xoff<2; xoff++) {
|
||||
_pfbtft[((y*2)+SCREENINSET_8875_Y+yoff)*RA8875_WIDTH+(x*2)+SCREENINSET_8875_X+xoff] = palette8[coloridx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t RA8875_t4::frameCount()
|
||||
{
|
||||
return _dma_frame_count;
|
||||
}
|
||||
|
||||
void RA8875_t4::writeCommand(const uint8_t d)
|
||||
{
|
||||
_startSend();
|
||||
_pspi->transfer(RA8875_CMDWRITE);
|
||||
_pspi->transfer(d);
|
||||
_endSend();
|
||||
}
|
||||
|
||||
void RA8875_t4::writeData16(uint16_t data)
|
||||
{
|
||||
_startSend();
|
||||
_pspi->transfer(RA8875_DATAWRITE);
|
||||
_pspi->transfer16(data);
|
||||
_endSend();
|
||||
}
|
||||
|
||||
void RA8875_t4::_writeData(uint8_t data)
|
||||
{
|
||||
_startSend();
|
||||
_pspi->transfer(RA8875_DATAWRITE);
|
||||
_pspi->transfer(data);
|
||||
_endSend();
|
||||
}
|
||||
|
||||
uint8_t RA8875_t4::_readData(bool stat)
|
||||
{
|
||||
// FIXME do we need to slow down for reads?
|
||||
_startSend();
|
||||
_pspi->transfer(stat ? RA8875_CMDREAD : RA8875_DATAREAD);
|
||||
uint8_t x = _pspi->transfer(0x00);
|
||||
_endSend();
|
||||
return x;
|
||||
}
|
||||
|
||||
void RA8875_t4::_writeRegister(const uint8_t reg, uint8_t val)
|
||||
{
|
||||
writeCommand(reg);
|
||||
_writeData(val);
|
||||
}
|
||||
|
||||
uint8_t RA8875_t4::_readRegister(const uint8_t reg)
|
||||
{
|
||||
writeCommand(reg);
|
||||
return _readData(false);
|
||||
}
|
||||
|
||||
boolean RA8875_t4::_waitPoll(uint8_t regname, uint8_t waitflag, uint8_t timeout)
|
||||
{
|
||||
uint8_t temp;
|
||||
unsigned long start_time = millis();
|
||||
|
||||
while (1) {
|
||||
temp = _readRegister(regname);
|
||||
if (!(temp & waitflag)) {
|
||||
return true;
|
||||
}
|
||||
if ((millis() - start_time) > timeout) {
|
||||
// timeout
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
void RA8875_t4::_waitBusy(uint8_t res)
|
||||
{
|
||||
uint8_t temp;
|
||||
unsigned long start = millis();//M.Sandercock
|
||||
do {
|
||||
if (res == 0x01) writeCommand(RA8875_DMACR);//dma
|
||||
temp = _readData(true);
|
||||
if ((millis() - start) > 10) return;
|
||||
} while ((temp & res) == res);
|
||||
}
|
||||
|
||||
void RA8875_t4::maybeUpdateTCR(uint32_t requested_tcr_state)
|
||||
{
|
||||
if ((_spi_tcr_current & TCR_MASK) != requested_tcr_state) {
|
||||
// PCS is the peripheral chip select used for the transfer
|
||||
_spi_tcr_current = (_spi_tcr_current & ~TCR_MASK) | requested_tcr_state ;
|
||||
// only output when Transfer queue is empty.
|
||||
while ((_pimxrt_spi->FSR & 0x1f) ) ;
|
||||
_pimxrt_spi->TCR = _spi_tcr_current; // update the TCR
|
||||
}
|
||||
}
|
||||
|
||||
void RA8875_t4::dmaInterrupt(void) {
|
||||
if (_dmaActiveDisplay)
|
||||
_dmaActiveDisplay->process_dma_interrupt();
|
||||
}
|
||||
|
||||
void RA8875_t4::process_dma_interrupt(void) {
|
||||
_dmatx.clearInterrupt();
|
||||
|
||||
_dma_frame_count++;
|
||||
if ((_dma_state & RA8875_DMA_CONT) == 0) {
|
||||
// Single refresh, or the user canceled, so release the CS pin
|
||||
while (_pimxrt_spi->FSR & 0x1f) ; // wait until transfer is done
|
||||
while (_pimxrt_spi->SR & LPSPI_SR_MBF) ; // ... and the module is not busy
|
||||
_dmatx.clearComplete();
|
||||
_pimxrt_spi->FCR = _spi_fcr_save;
|
||||
_pimxrt_spi->DER = 0; // turn off tx and rx DMA
|
||||
_pimxrt_spi->CR = LPSPI_CR_MEN | LPSPI_CR_RRF | LPSPI_CR_RTF; //RRF: reset receive FIFO; RTF: reset transmit FIFO; MEN: enable module
|
||||
_pimxrt_spi->SR = 0x3f00; // Clear error flags (these are w1c flags - "write 1 to clear")
|
||||
maybeUpdateTCR(LPSPI_TCR_FRAMESZ(7));
|
||||
_endSend();
|
||||
_dma_state &= ~RA8875_DMA_ACTIVE;
|
||||
_dmaActiveDisplay = 0;
|
||||
} else {
|
||||
// Try to flush memory
|
||||
if ((uint32_t)_pfbtft >= 0x20200000u)
|
||||
arm_dcache_flush(_pfbtft, RA8875_WIDTH*RA8875_HEIGHT);
|
||||
}
|
||||
// make sure the code is synchronized - memory access must be
|
||||
// complete before we continue
|
||||
asm("dsb");
|
||||
}
|
||||
|
||||
// Other possible methods, that I don't think we'll need:
|
||||
// void RA8875_t4::setFrameCompleteCB(void (*pcb)(), bool fCallAlsoHalfDone)
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
#ifndef _RA8875_T4_H
|
||||
#define _RA8875_T4_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
#include <DMAChannel.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "basedisplay.h"
|
||||
|
||||
#define RA8875_WIDTH 800
|
||||
#define RA8875_HEIGHT 480
|
||||
|
||||
#define _RA8875_WAITPOLL_TIMEOUT_DCR_LINESQUTRI_STATUS 20
|
||||
|
||||
enum {
|
||||
RA8875_DMA_INIT=0x01,
|
||||
RA8875_DMA_EVER_INIT=0x08,
|
||||
RA8875_DMA_CONT=0x02,
|
||||
RA8875_DMA_FINISH=0x04,
|
||||
RA8875_DMA_ACTIVE=0x80
|
||||
};
|
||||
|
||||
class RA8875_t4 : public BaseDisplay {
|
||||
public:
|
||||
RA8875_t4(uint8_t cs_pin, uint8_t rst_pin, uint8_t mosi_pin, uint8_t sck_pin, uint8_t miso_pin, uint8_t dc_pin=255); // dc pin is unused for this display but it's needed for the ILI and base class.
|
||||
|
||||
~RA8875_t4();
|
||||
|
||||
virtual void begin(uint32_t spi_clock=30000000u, uint32_t spi_clock_read=2000000);
|
||||
|
||||
virtual void fillWindow(uint8_t coloridx = 0x00);
|
||||
|
||||
virtual void setFrameBuffer(uint8_t *frame_buffer);
|
||||
|
||||
virtual bool asyncUpdateActive();
|
||||
virtual bool updateScreenAsync(bool update_cont = false);
|
||||
|
||||
virtual void drawPixel(int16_t x, int16_t y, uint16_t color);
|
||||
|
||||
virtual void cacheApplePixel(uint16_t x, uint16_t y, uint8_t coloridx);
|
||||
virtual void cacheDoubleWideApplePixel(uint16_t x, uint16_t y, uint8_t coloridx);
|
||||
|
||||
virtual uint32_t frameCount();
|
||||
|
||||
uint8_t color16To8bpp(uint16_t color) __attribute__((always_inline)) {
|
||||
return ((color & 0xe000) >> 8) | ((color & 0x700) >> 6) | ((color & 0x18) >> 3);
|
||||
}
|
||||
|
||||
private:
|
||||
void _initializeTFT();
|
||||
void initDMASettings();
|
||||
|
||||
// These are the old style RA8875 calls -- replace them ***
|
||||
void writeCommand(const uint8_t d);
|
||||
void writeData16(uint16_t data);
|
||||
|
||||
void _writeData(uint8_t data);
|
||||
void _writeRegister(const uint8_t reg, uint8_t val);
|
||||
|
||||
uint8_t _readData(bool stat);
|
||||
uint8_t _readRegister(const uint8_t reg);
|
||||
|
||||
void _waitBusy(uint8_t res);
|
||||
|
||||
boolean _waitPoll(uint8_t regname, uint8_t waitflag, uint8_t timeout);
|
||||
|
||||
void maybeUpdateTCR(uint32_t requested_tcr_state);
|
||||
|
||||
static void dmaInterrupt(void);
|
||||
void process_dma_interrupt(void);
|
||||
|
||||
protected:
|
||||
uint8_t _cs, _miso, _mosi, _sck, _rst;
|
||||
|
||||
SPIClass *_pspi;
|
||||
IMXRT_LPSPI_t *_pimxrt_spi;
|
||||
SPIClass::SPI_Hardware_t *_spi_hardware;
|
||||
uint32_t _spi_clock; // desired clock
|
||||
uint32_t _spi_clock_read;
|
||||
uint32_t _clock; // current clock, used in starting transactions (b/c we have to slow down sometimes)
|
||||
|
||||
// DMA stuff. The _dmasettings[] and _dmatx can't be member
|
||||
// variables. If they are, then the object will work if it's
|
||||
// statically allocated; but dynamically allocated RA8875_t4 objects
|
||||
// would be malloc()'d in RAM2, which is a problem for DMA.
|
||||
// So instead they're static globals in the module.
|
||||
// DMASetting _dmasettings[12];
|
||||
// DMAChannel _dmatx;
|
||||
uint32_t _spi_fcr_save;
|
||||
uint8_t *_pfbtft;
|
||||
volatile uint8_t _dma_state;
|
||||
uint32_t _spi_tcr_current;
|
||||
volatile uint32_t _dma_frame_count;
|
||||
|
||||
protected:
|
||||
void DIRECT_WRITE_LOW(volatile uint32_t * base, uint32_t mask) __attribute__((always_inline)) {
|
||||
*(base+34) = mask;
|
||||
}
|
||||
void DIRECT_WRITE_HIGH(volatile uint32_t * base, uint32_t mask) __attribute__((always_inline)) {
|
||||
*(base+33) = mask;
|
||||
}
|
||||
|
||||
/* These are old-style function names, but with new-style contents */
|
||||
void _startSend() __attribute__((always_inline)) {
|
||||
_pspi->beginTransaction(SPISettings(_clock, MSBFIRST, SPI_MODE3));
|
||||
_spi_tcr_current = _pimxrt_spi->TCR;
|
||||
// DIRECT_WRITE_LOW(_csport, _cspinmask);
|
||||
digitalWriteFast(_cs, LOW);
|
||||
}
|
||||
|
||||
void _endSend() __attribute__((always_inline)) {
|
||||
// DIRECT_WRITE_HIGH(_csport, _cspinmask);
|
||||
digitalWriteFast(_cs, HIGH);
|
||||
_pspi->endTransaction();
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef __BASE_DISPLAY_H
|
||||
#define __BASE_DISPLAY_H
|
||||
|
||||
#define RGBto565(r,g,b) ((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | ((b) >> 3))
|
||||
#define _565toR(c) ( ((c) & 0xF800) >> 8 )
|
||||
#define _565toG(c) ( ((c) & 0x07E0) >> 3 )
|
||||
#define _565toB(c) ( ((c) & 0x001F) << 3 )
|
||||
#define RGBto332(r,g,b) ((((r) & 0xE0)) | (((g) & 0xE0) >> 3) | ((b) >> 6))
|
||||
#define luminanceFromRGB(r,g,b) ( ((r)*0.2126) + ((g)*0.7152) + ((b)*0.0722) )
|
||||
#define _565To332(c) ((((c) & 0xe000) >> 8) | (((c) & 0x700) >> 6) | (((c) & 0x18) >> 3))
|
||||
#define _332To565(c) ((((c) & 0xe0) << 8) | (((c) & 0x1c) << 6) | ((c) & 0x03))
|
||||
|
||||
//#define blendColors(a,b) RGBto565( (_565toR(a) + _565toR(b))/2, (_565toG(a) + _565toG(b))/2, (_565toB(a) + _565toB(b))/2 )
|
||||
|
||||
class BaseDisplay {
|
||||
public:
|
||||
BaseDisplay(uint8_t cs_pin, uint8_t rst_pin, uint8_t mosi_pin, uint8_t sck_pin, uint8_t miso_pin, uint8_t dc_pin=255) {};
|
||||
|
||||
~BaseDisplay() {};
|
||||
|
||||
virtual void begin(uint32_t spi_clock=30000000u, uint32_t spi_clock_read=2000000) = 0;
|
||||
|
||||
virtual void fillWindow(uint8_t coloridx = 0x00) = 0;
|
||||
|
||||
virtual void setFrameBuffer(uint8_t *frame_buffer) = 0;
|
||||
|
||||
virtual bool asyncUpdateActive();
|
||||
virtual bool updateScreenAsync(bool update_cont = false) = 0;
|
||||
|
||||
virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0;
|
||||
|
||||
// Apple interface methods
|
||||
virtual void cacheApplePixel(uint16_t x, uint16_t y, uint8_t coloridx) = 0;
|
||||
virtual void cacheDoubleWideApplePixel(uint16_t x, uint16_t y, uint8_t coloridx) = 0;
|
||||
|
||||
virtual uint32_t frameCount() = 0;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1 @@
|
|||
../image-8875-apple.h
|
|
@ -0,0 +1 @@
|
|||
../image-8875-bg.h
|
|
@ -0,0 +1 @@
|
|||
../image-8875-drivelatches.h
|
|
@ -0,0 +1 @@
|
|||
../image-9341-applebitmap.h
|
|
@ -0,0 +1 @@
|
|||
../image-9341-bg.h
|
|
@ -0,0 +1 @@
|
|||
../image-9341-drivelatches.h
|
|
@ -0,0 +1,99 @@
|
|||
#ifndef __PALETTE_H
|
||||
#define __PALETTE_H
|
||||
|
||||
static const uint8_t palette8[16] = {
|
||||
0x00, // 0 black
|
||||
0xC0, // 1 magenta
|
||||
0x02, // 2 dark blue
|
||||
0xA6, // 3 purple
|
||||
0x10, // 4 dark green
|
||||
0x6D, // 5 dark grey
|
||||
0x0F, // 6 med blue
|
||||
0x17, // 7 light blue
|
||||
0x88, // 8 brown
|
||||
0xE0, // 9 orange
|
||||
0x96, // 10 light gray
|
||||
0xF2, // 11 pink
|
||||
0x1C, // 12 green
|
||||
0xFC, // 13 yellow
|
||||
0x9E, // 14 aqua
|
||||
0xFF // 15 white
|
||||
};
|
||||
|
||||
static const uint16_t palette16[16] = {
|
||||
0x0000, // 0 black
|
||||
0xC006, // 1 magenta
|
||||
0x0010, // 2 dark blue
|
||||
0xA1B5, // 3 purple
|
||||
0x0480, // 4 dark green
|
||||
0x6B4D, // 5 dark grey
|
||||
0x1B9F, // 6 med blue
|
||||
0x0DFD, // 7 light blue
|
||||
0x92A5, // 8 brown
|
||||
0xF8C5, // 9 orange
|
||||
0x9555, // 10 light gray
|
||||
0xFCF2, // 11 pink
|
||||
0x07E0, // 12 green
|
||||
0xFFE0, // 13 yellow
|
||||
0x87F0, // 14 aqua
|
||||
0xFFFF // 15 white
|
||||
};
|
||||
|
||||
static const uint8_t mix8[16][16] = {
|
||||
0x00, 0x29, 0x28, 0x2D, 0x28, 0x49, 0x28, 0x6D, 0x24, 0x69, 0x24, 0x4D, 0x6D, 0x6D, 0x6D, 0x6D,
|
||||
0x29, 0xA1, 0x62, 0xA2, 0x02, 0x52, 0x42, 0xAB, 0x0E, 0x3B, 0x8A, 0xC6, 0x0B, 0x37, 0x47, 0x7B,
|
||||
0x28, 0x62, 0x02, 0x42, 0x0E, 0x31, 0x0A, 0x2B, 0x0C, 0x18, 0x46, 0x87, 0x16, 0x39, 0x32, 0x79,
|
||||
0x2D, 0xA2, 0x42, 0xA3, 0x0A, 0x56, 0x03, 0x8B, 0x16, 0x3E, 0x8A, 0xEB, 0x37, 0x5F, 0x4F, 0x9E,
|
||||
0x28, 0x02, 0x0E, 0x0A, 0x10, 0x70, 0x11, 0x37, 0x2C, 0x98, 0x2A, 0x2B, 0x14, 0x78, 0x35, 0xB9,
|
||||
0x49, 0x52, 0x31, 0x56, 0x70, 0x91, 0x55, 0x9A, 0x8C, 0xD1, 0x72, 0x9B, 0xB9, 0xDA, 0x99, 0xDA,
|
||||
0x28, 0x42, 0x0A, 0x03, 0x11, 0x55, 0x12, 0x4F, 0x10, 0x58, 0x2A, 0x67, 0x19, 0x39, 0x3A, 0x99,
|
||||
0x6D, 0xAB, 0x2B, 0x8B, 0x37, 0x9A, 0x4F, 0x93, 0x35, 0x7E, 0x92, 0xD3, 0x7F, 0x9F, 0x9B, 0xDF,
|
||||
0x24, 0x0E, 0x0C, 0x16, 0x2C, 0x8C, 0x10, 0x35, 0x68, 0xAC, 0x2D, 0x36, 0x94, 0xB4, 0x54, 0xB1,
|
||||
0x69, 0x3B, 0x18, 0x3E, 0x98, 0xD1, 0x58, 0x7E, 0xAC, 0xED, 0x76, 0x7F, 0xFC, 0xF5, 0xBD, 0xF6,
|
||||
0x24, 0x8A, 0x46, 0x8A, 0x2A, 0x72, 0x2A, 0x92, 0x2D, 0x76, 0x6D, 0xAE, 0x56, 0x76, 0x72, 0xB6,
|
||||
0x4D, 0xC6, 0x87, 0xEB, 0x2B, 0x9B, 0x67, 0xD3, 0x36, 0x7F, 0xAE, 0xEF, 0x57, 0x7F, 0x6F, 0xBF,
|
||||
0x6D, 0x0B, 0x16, 0x37, 0x14, 0xB9, 0x19, 0x7F, 0x94, 0xFC, 0x56, 0x57, 0x7C, 0xDD, 0x5D, 0xFE,
|
||||
0x6D, 0x37, 0x39, 0x5F, 0x78, 0xDA, 0x39, 0x9F, 0xB4, 0xF5, 0x76, 0x7F, 0xDD, 0xFD, 0x9D, 0xFA,
|
||||
0x6D, 0x47, 0x32, 0x4F, 0x35, 0x99, 0x3A, 0x9B, 0x54, 0xBD, 0x72, 0x6F, 0x5D, 0x9D, 0x7E, 0xFE,
|
||||
0x6D, 0x7B, 0x79, 0x9E, 0xB9, 0xDA, 0x99, 0xDF, 0xB1, 0xF6, 0xB6, 0xBF, 0xFE, 0xFA, 0xFE, 0xFF,
|
||||
};
|
||||
|
||||
static const uint16_t mix16[16][16] = {
|
||||
0x0000, 0x2AA9, 0x2204, 0x3B49, 0x3A04, 0x4A48, 0x3AC5, 0x63EC, 0x3943, 0x7AAA, 0x39E7, 0x5BEE, 0x7348, 0x7B6B, 0x6BAA, 0x7BEF,
|
||||
0x2AA9, 0xA889, 0x7032, 0xB8B3, 0x0052, 0x4CB4, 0x5056, 0xBA7A, 0x03D2, 0x2EB9, 0x9231, 0xD1F1, 0x1AF9, 0x3D7A, 0x41D9, 0x76B8,
|
||||
0x2204, 0x7032, 0x0050, 0x4055, 0x0390, 0x3C8A, 0x0213, 0x3A18, 0x03E5, 0x1E05, 0x49B0, 0x8978, 0x15B2, 0x2E0D, 0x2CB7, 0x660C,
|
||||
0x3B49, 0xB8B3, 0x4055, 0xA8DA, 0x0A75, 0x55D4, 0x0878, 0x8ABD, 0x0D30, 0x2F51, 0x9275, 0xEA3B, 0x25BB, 0x4759, 0x43BB, 0x8735,
|
||||
0x3A04, 0x0052, 0x0390, 0x0A75, 0x0405, 0x6487, 0x04EF, 0x3D58, 0x33E0, 0x9603, 0x32D0, 0x2A38, 0x15A2, 0x6605, 0x2DCD, 0xB60C,
|
||||
0x4A48, 0x4CB4, 0x3C8A, 0x55D4, 0x6487, 0x9CAF, 0x4548, 0x9675, 0x8BA6, 0xCCED, 0x7470, 0x8659, 0xAE0B, 0xCE10, 0x962F, 0xCE17,
|
||||
0x3AC5, 0x5056, 0x0213, 0x0878, 0x04EF, 0x4548, 0x0456, 0x43FB, 0x04A0, 0x56C3, 0x3A13, 0x61BB, 0x166C, 0x36C8, 0x2E97, 0x96CD,
|
||||
0x63EC, 0xBA7A, 0x3A18, 0x8ABD, 0x3D58, 0x9675, 0x43FB, 0x9CFF, 0x3DED, 0x77F0, 0x9C57, 0xDC5F, 0x679B, 0x8FF8, 0x86DE, 0xCFF9,
|
||||
0x3943, 0x03D2, 0x03E5, 0x0D30, 0x33E0, 0x8BA6, 0x04A0, 0x3DED, 0x7AE0, 0xBB43, 0x33ED, 0x2DB7, 0x9582, 0xBD25, 0x5DA5, 0xBC0B,
|
||||
0x7AAA, 0x2EB9, 0x1E05, 0x2F51, 0x9603, 0xCCED, 0x56C3, 0x77F0, 0xBB43, 0xFB88, 0x6DF2, 0x67FB, 0xF727, 0xFDCC, 0xBFAB, 0xFD74,
|
||||
0x39E7, 0x9231, 0x49B0, 0x9275, 0x32D0, 0x7470, 0x3A13, 0x9C57, 0x33ED, 0x6DF2, 0x734F, 0xBBD7, 0x5D36, 0x7DF6, 0x7476, 0xADF6,
|
||||
0x5BEE, 0xD1F1, 0x8978, 0xEA3B, 0x2A38, 0x8659, 0x61BB, 0xDC5F, 0x2DB7, 0x67FB, 0xBBD7, 0xFBDA, 0x551E, 0x7F7F, 0x73DE, 0xBFFD,
|
||||
0x7348, 0x1AF9, 0x15B2, 0x25BB, 0x15A2, 0xAE0B, 0x166C, 0x679B, 0x9582, 0xF727, 0x5D36, 0x551E, 0x7725, 0xC78A, 0x4F4B, 0xF712,
|
||||
0x7B6B, 0x3D7A, 0x2E0D, 0x4759, 0x6605, 0xCE10, 0x36C8, 0x8FF8, 0xBD25, 0xFDCC, 0x7DF6, 0x7F7F, 0xC78A, 0xFFAF, 0x97AE, 0xFED7,
|
||||
0x6BAA, 0x41D9, 0x2CB7, 0x43BB, 0x2DCD, 0x962F, 0x2E97, 0x86DE, 0x5DA5, 0xBFAB, 0x7476, 0x73DE, 0x4F4B, 0x97AE, 0x6F76, 0xE7B6,
|
||||
0x7BEF, 0x76B8, 0x660C, 0x8735, 0xB60C, 0xCE17, 0x96CD, 0xCFF9, 0xBC0B, 0xFD74, 0xADF6, 0xBFFD, 0xF712, 0xFED7, 0xE7B6, 0xFFFF,
|
||||
};
|
||||
|
||||
static const uint32_t mix32[16][16] = {
|
||||
0x00000000, 0x002F564E, 0x00214120, 0x003A684C, 0x003B4120, 0x004F4A47, 0x003E5A2D, 0x00677F67, 0x003D2A1E, 0x007F5651, 0x00393F3B, 0x005E7F74, 0x00736A44, 0x007F6D5E, 0x006E7756, 0x007F7F7F,
|
||||
0x002F564E, 0x00AC114D, 0x00770797, 0x00BE159C, 0x00070A97, 0x004A94A5, 0x005009B0, 0x00BB4DD5, 0x00077893, 0x0028D5C8, 0x00954589, 0x00D53E8C, 0x001D5DC9, 0x003EADD5, 0x004439CD, 0x0075D5C3,
|
||||
0x00214120, 0x00770797, 0x00000883, 0x00430AAA, 0x00007083, 0x00399157, 0x0000419C, 0x003B40C1, 0x00007E2C, 0x001AC128, 0x004C3481, 0x008C2EC1, 0x0011B491, 0x002EC16C, 0x002997B8, 0x0063C160,
|
||||
0x003A684C, 0x00BE159C, 0x00430AAA, 0x00A919D1, 0x000A4FAA, 0x0054B8A0, 0x000D0CC3, 0x008F56E8, 0x000AA582, 0x002EE88C, 0x00904FA8, 0x00E845DD, 0x0022B4DB, 0x0046E8CF, 0x004076DF, 0x0082E7AA,
|
||||
0x003B4120, 0x00070A97, 0x00007083, 0x000A4FAA, 0x0000832D, 0x00609139, 0x00009C7B, 0x003BA9C1, 0x00377E00, 0x0090C11A, 0x00345981, 0x002E44C1, 0x0012B411, 0x0064C12E, 0x0029B868, 0x00B0C160,
|
||||
0x004F4A47, 0x004A94A5, 0x00399157, 0x0054B8A0, 0x00609139, 0x009F967E, 0x0044AA43, 0x0092CFA8, 0x008C7737, 0x00CF9E6E, 0x00738F87, 0x0083CBCF, 0x00AFC25F, 0x00CFC283, 0x0096C67B, 0x00CFC1B9,
|
||||
0x003E5A2D, 0x005009B0, 0x0000419C, 0x000D0CC3, 0x00009C7B, 0x0044AA43, 0x00008AB5, 0x00437DDA, 0x00009700, 0x0050DA1E, 0x003F429A, 0x006434DA, 0x0013CD64, 0x0034DA40, 0x002FD1BE, 0x0096DA6D,
|
||||
0x00677F67, 0x00BB4DD5, 0x003B40C1, 0x008F56E8, 0x003BA9C1, 0x0092CFA8, 0x00437DDA, 0x009D9DFF, 0x003ABC6C, 0x0072FF82, 0x009B89BF, 0x00D98BFF, 0x0062F2D8, 0x008CFFC0, 0x0084D8F6, 0x00CEFFCE,
|
||||
0x003D2A1E, 0x00077893, 0x00007E2C, 0x000AA582, 0x00377E00, 0x008C7737, 0x00009700, 0x003ABC6C, 0x007A5D00, 0x00BC6B1A, 0x00327C68, 0x002DB4BC, 0x0090B010, 0x00BCA52D, 0x0059B428, 0x00BC825E,
|
||||
0x007F5651, 0x0028D5C8, 0x001AC128, 0x002EE88C, 0x0090C11A, 0x00CF9E6E, 0x0050DA1E, 0x0072FF82, 0x00BC6B1A, 0x00FF7146, 0x0068BF90, 0x0060FFDD, 0x00F2E638, 0x00FFBB60, 0x00BAF65A, 0x00FFADA3,
|
||||
0x00393F3B, 0x00954589, 0x004C3481, 0x00904FA8, 0x00345981, 0x00738F87, 0x003F429A, 0x009B89BF, 0x00327C68, 0x0068BF90, 0x0077687F, 0x00BF7BBD, 0x005AA4B2, 0x007CBFB1, 0x00748EB6, 0x00ADBFB3,
|
||||
0x005E7F74, 0x00D53E8C, 0x008C2EC1, 0x00E845DD, 0x002E44C1, 0x0083CBCF, 0x006434DA, 0x00D98BFF, 0x002DB4BC, 0x0060FFDD, 0x00BF7BBD, 0x00FF79D0, 0x0051A3F2, 0x007AEDFF, 0x00727AF6, 0x00BCFFE9,
|
||||
0x00736A44, 0x001D5DC9, 0x0011B491, 0x0022B4DB, 0x0012B411, 0x00AFC25F, 0x0013CD64, 0x0062F2D8, 0x0090B010, 0x00F2E638, 0x005AA4B2, 0x0051A3F2, 0x0070E62B, 0x00C6F251, 0x004BEA58, 0x00F2E090,
|
||||
0x007F6D5E, 0x003EADD5, 0x002EC16C, 0x0046E8CF, 0x0064C12E, 0x00CFC283, 0x0034DA40, 0x008CFFC0, 0x00BCA52D, 0x00FFBB60, 0x007CBFB1, 0x007AEDFF, 0x00C6F251, 0x00FFF47A, 0x0097F673, 0x00FFDBBD,
|
||||
0x006E7756, 0x004439CD, 0x002997B8, 0x004076DF, 0x0029B868, 0x0096C67B, 0x002FD1BE, 0x0084D8F6, 0x0059B428, 0x00BAF65A, 0x00748EB6, 0x00727AF6, 0x004BEA58, 0x0097F673, 0x006BEEB1, 0x00E4F6B3,
|
||||
0x007F7F7F, 0x0075D5C3, 0x0063C160, 0x0082E7AA, 0x00B0C160, 0x00CFC1B9, 0x0096DA6D, 0x00CEFFCE, 0x00BC825E, 0x00FFADA3, 0x00ADBFB3, 0x00BCFFE9, 0x00F2E090, 0x00FFDBBD, 0x00E4F6B3, 0x00FFFFFF,
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1 @@
|
|||
../physicaldisplay.cpp
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* https://forum.pjrc.com/threads/186-Teensy-3-fault-handler-demonstration?highlight=crash+handler
|
||||
*
|
||||
* call this from setup():
|
||||
* enableFaultHandler();
|
||||
*
|
||||
* On crash you see something like:
|
||||
* !!!! Crashed at pc=0x490, lr=0x55B.
|
||||
*
|
||||
* which you can interpret thusly:
|
||||
* $ arm-none-eabi-addr2line -s -f -C -e main.elf 0x490 0x55B
|
||||
* Print:: println(char const*)
|
||||
* Print.h:47
|
||||
* main
|
||||
* main_crash.cpp:86
|
||||
*/
|
||||
|
||||
#define SCB_SHCSR_USGFAULTENA (uint32_t)1<<18
|
||||
#define SCB_SHCSR_BUSFAULTENA (uint32_t)1<<17
|
||||
#define SCB_SHCSR_MEMFAULTENA (uint32_t)1<<16
|
||||
|
||||
#define SCB_SHPR1_USGFAULTPRI *(volatile uint8_t *)0xE000ED20
|
||||
#define SCB_SHPR1_BUSFAULTPRI *(volatile uint8_t *)0xE000ED19
|
||||
#define SCB_SHPR1_MEMFAULTPRI *(volatile uint8_t *)0xE000ED18
|
||||
|
||||
// enable bus, usage, and mem fault handlers.
|
||||
void enableFaultHandler()
|
||||
{
|
||||
SCB_SHCSR |= SCB_SHCSR_BUSFAULTENA | SCB_SHCSR_USGFAULTENA | SCB_SHCSR_MEMFAULTENA;
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
void __attribute__((naked)) _fault_isr () {
|
||||
uint32_t* sp=0;
|
||||
// this is from "Definitive Guide to the Cortex M3" pg 423
|
||||
asm volatile ( "TST LR, #0x4\n\t" // Test EXC_RETURN number in LR bit 2
|
||||
"ITE EQ\n\t" // if zero (equal) then
|
||||
"MRSEQ %0, MSP\n\t" // Main Stack was used, put MSP in sp
|
||||
"MRSNE %0, PSP\n\t" // else Process stack was used, put PSP in sp
|
||||
: "=r" (sp) : : "cc");
|
||||
|
||||
Serial.print("!!!! Crashed at pc=0x");
|
||||
Serial.print(sp[6], 16);
|
||||
Serial.print(", lr=0x");
|
||||
Serial.print(sp[5], 16);
|
||||
Serial.println(".");
|
||||
|
||||
Serial.flush();
|
||||
|
||||
// allow USB interrupts to preempt us:
|
||||
SCB_SHPR1_BUSFAULTPRI = (uint8_t)255;
|
||||
SCB_SHPR1_USGFAULTPRI = (uint8_t)255;
|
||||
SCB_SHPR1_MEMFAULTPRI = (uint8_t)255;
|
||||
|
||||
while (1) {
|
||||
digitalWrite(13, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(13, LOW);
|
||||
delay(100);
|
||||
|
||||
asm volatile (
|
||||
"WFI" // Wait For Interrupt.
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hard_fault_isr(void) __attribute__ ((alias("_fault_isr")));
|
||||
void memmanage_fault_isr(void) __attribute__ ((alias("_fault_isr")));
|
||||
void bus_fault_isr(void) __attribute__ ((alias("_fault_isr")));
|
||||
void usage_fault_isr(void) __attribute__ ((alias("_fault_isr")));
|
|
@ -1,24 +1,22 @@
|
|||
#include <ctype.h> // isgraph
|
||||
#include <DMAChannel.h>
|
||||
|
||||
#include "teensy-display.h"
|
||||
#include "iocompat.h"
|
||||
|
||||
#include "appleui.h"
|
||||
// FIXME should be able to omit this include and rely on the xterns, which
|
||||
// would prove it's linking properly
|
||||
#include "font.h"
|
||||
extern const unsigned char ucase_glyphs[512];
|
||||
extern const unsigned char lcase_glyphs[256];
|
||||
extern const unsigned char mousetext_glyphs[256];
|
||||
extern const unsigned char interface_glyphs[256];
|
||||
|
||||
#include "globals.h"
|
||||
#include "applevm.h"
|
||||
|
||||
#include <SPI.h>
|
||||
#define _clock 50000000
|
||||
#include "RA8875_t4.h"
|
||||
#include "ILI9341_wrap.h"
|
||||
|
||||
#include "images.h"
|
||||
|
||||
uint8_t *dmaBuffer = NULL;
|
||||
uint16_t *dmaBuffer16 = NULL;
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
#define PIN_RST 8
|
||||
#define PIN_DC 9
|
||||
|
@ -27,326 +25,219 @@ extern const unsigned char interface_glyphs[256];
|
|||
#define PIN_MISO 1
|
||||
#define PIN_SCK 27
|
||||
|
||||
#define SCREENINSET_X (18*TEENSYDISPLAY_SCALE)
|
||||
#define SCREENINSET_Y (13*TEENSYDISPLAY_SCALE)
|
||||
|
||||
// RGB map of each of the lowres colors
|
||||
const uint16_t loresPixelColors[16] = { 0x0000, // 0 black
|
||||
0xC006, // 1 magenta
|
||||
0x0010, // 2 dark blue
|
||||
0xA1B5, // 3 purple
|
||||
0x0480, // 4 dark green
|
||||
0x6B4D, // 5 dark grey
|
||||
0x1B9F, // 6 med blue
|
||||
0x0DFD, // 7 light blue
|
||||
0x92A5, // 8 brown
|
||||
0xF8C5, // 9 orange
|
||||
0x9555, // 10 light gray
|
||||
0xFCF2, // 11 pink
|
||||
0x07E0, // 12 green
|
||||
0xFFE0, // 13 yellow
|
||||
0x87F0, // 14 aqua
|
||||
0xFFFF // 15 white
|
||||
};
|
||||
|
||||
// This definition can't live in the class header because of the
|
||||
// DMAMEM adornment
|
||||
DMAMEM uint16_t dmaBuffer[TEENSYDISPLAY_HEIGHT][TEENSYDISPLAY_WIDTH];
|
||||
|
||||
#define RGBto565(r,g,b) ((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | ((b) >> 3))
|
||||
#define _565toR(c) ( ((c) & 0xF800) >> 8 )
|
||||
#define _565toG(c) ( ((c) & 0x07E0) >> 3 )
|
||||
#define _565toB(c) ( ((c) & 0x001F) << 3 )
|
||||
#define luminanceFromRGB(r,g,b) ( ((r)*0.2126) + ((g)*0.7152) + ((b)*0.0722) )
|
||||
|
||||
|
||||
ILI9341_t3n tft = ILI9341_t3n(PIN_CS, PIN_DC, PIN_RST, PIN_MOSI, PIN_SCK, PIN_MISO);
|
||||
|
||||
DMAChannel dmatx;
|
||||
DMASetting dmaSetting;
|
||||
|
||||
|
||||
TeensyDisplay::TeensyDisplay()
|
||||
{
|
||||
memset(dmaBuffer, 0x80, sizeof(dmaBuffer));
|
||||
driveIndicator[0] = driveIndicator[1] = true; // assume on so they will redraw immediately the first time
|
||||
|
||||
tft.begin(_clock);
|
||||
tft.setRotation(3);
|
||||
tft.setFrameBuffer((uint16_t *)dmaBuffer);
|
||||
tft.useFrameBuffer(true);
|
||||
tft.fillScreen(ILI9341_BLACK);
|
||||
shellImage = NULL;
|
||||
d1OpenImage = d1ClosedImage = d2OpenImage = d2ClosedImage = NULL;
|
||||
appleImage = NULL;
|
||||
|
||||
// FIXME abstract pin number, don't hard code it
|
||||
pinMode(11, INPUT_PULLUP);
|
||||
delay(10); // let it rise before reading it
|
||||
|
||||
if (digitalRead(11)) {
|
||||
// Default: use older, smaller but faster, ILI display if pin 11 is not connected to ground
|
||||
Serial.println(" using ILI9341 display");
|
||||
use8875 = false;
|
||||
|
||||
dmaBuffer16 = (uint16_t *)malloc((320*240)*2+32); // malloc() happens in the DMAMEM area (RAM2)
|
||||
// And we have to be sure dmaBuffer16 is 32-byte aligned for DMA purposes
|
||||
// so we intentionally alloc'd an extra 32 bytes in order to shift here
|
||||
dmaBuffer16 = (uint16_t *)(((uintptr_t)dmaBuffer16 + 32) &
|
||||
~((uintptr_t)(31)));
|
||||
|
||||
tft = new ILI9341_Wrap(PIN_CS, PIN_RST, PIN_MOSI, PIN_SCK, PIN_MISO, PIN_DC);
|
||||
|
||||
driveIndicator[0] = driveIndicator[1] = false;
|
||||
driveIndicatorDirty = true;
|
||||
// Load the 9341 images
|
||||
getImageInfoAndData(IMG_9341_SHELL, &shellWidth, &shellHeight, &shellImage);
|
||||
getImageInfoAndData(IMG_9341_D1OPEN, &driveWidth, &driveHeight, &d1OpenImage);
|
||||
getImageInfoAndData(IMG_9341_D1CLOSED, &driveWidth, &driveHeight, &d1ClosedImage);
|
||||
getImageInfoAndData(IMG_9341_D2OPEN, &driveWidth, &driveHeight, &d2OpenImage);
|
||||
getImageInfoAndData(IMG_9341_D2CLOSED, &driveWidth, &driveHeight, &d2ClosedImage);
|
||||
getImageInfoAndData(IMG_9341_APPLEBATTERY, &appleImageWidth, &appleImageHeight, &appleImage);
|
||||
|
||||
tft->begin(50000000u);
|
||||
tft->setFrameBuffer((uint8_t *)dmaBuffer16);
|
||||
} else {
|
||||
// If someone grounded pin 11, then use the new RA8875 display
|
||||
Serial.println(" using RA8875 display");
|
||||
use8875 = true;
|
||||
|
||||
dmaBuffer = (uint8_t *)malloc(800*480+32); // malloc() happens in the DMAMEM area (RAM2)
|
||||
// And we have to be sure dmaBuffer is 32-byte aligned for DMA purposes
|
||||
// so we intentionally alloc'd an extra 32 bytes in order to shift here
|
||||
dmaBuffer = (uint8_t *)(((uintptr_t)dmaBuffer + 32) &
|
||||
~((uintptr_t)(31)));
|
||||
|
||||
tft = new RA8875_t4(PIN_CS, PIN_RST, PIN_MOSI, PIN_SCK, PIN_MISO);
|
||||
|
||||
// Load the 8875 images
|
||||
getImageInfoAndData(IMG_8875_SHELL, &shellWidth, &shellHeight, &shellImage);
|
||||
getImageInfoAndData(IMG_8875_D1OPEN, &driveWidth, &driveHeight, &d1OpenImage);
|
||||
getImageInfoAndData(IMG_8875_D1CLOSED, &driveWidth, &driveHeight, &d1ClosedImage);
|
||||
getImageInfoAndData(IMG_8875_D2OPEN, &driveWidth, &driveHeight, &d2OpenImage);
|
||||
getImageInfoAndData(IMG_8875_D2CLOSED, &driveWidth, &driveHeight, &d2ClosedImage);
|
||||
getImageInfoAndData(IMG_8875_APPLEBATTERY, &appleImageWidth, &appleImageHeight, &appleImage);
|
||||
// 30MHz: solid performance, 9 FPS
|
||||
// 57.5MHz: solid performance, 14/15 FPS
|
||||
// 60MHz: unexpected palatte shifts & (may be audio overruns, needs checking since bumping up buffer sizes) 17 FPS
|
||||
// And I can't get the SPI bus working at 80MHz or higher. Not sure why yet...
|
||||
tft->begin(57500000);
|
||||
tft->setFrameBuffer((uint8_t *)dmaBuffer);
|
||||
}
|
||||
|
||||
tft->fillWindow();
|
||||
}
|
||||
|
||||
TeensyDisplay::~TeensyDisplay()
|
||||
{
|
||||
/* FIXME: we mucked with these after alloc to align them, so we can't free them from their offset addresses; need to keep track of the original malloc'd address instead
|
||||
if (dmaBuffer)
|
||||
free(dmaBuffer);
|
||||
if (dmaBuffer16)
|
||||
free(dmaBuffer16);
|
||||
*/
|
||||
}
|
||||
|
||||
void TeensyDisplay::flush()
|
||||
{
|
||||
// Nothing to flush, b/c the DMA driver is regularly flushing everything
|
||||
}
|
||||
// Take one of the abstracted image constants, figure out which one it
|
||||
// is based on the current display, and display it via
|
||||
// drawImageOfSizeAt.
|
||||
|
||||
void TeensyDisplay::redraw()
|
||||
void TeensyDisplay::drawUIImage(uint8_t imageIdx)
|
||||
{
|
||||
g_ui->drawStaticUIElement(UIeOverlay);
|
||||
|
||||
if (g_vm && g_ui) {
|
||||
g_ui->drawOnOffUIElement(UIeDisk1_state, ((AppleVM *)g_vm)->DiskName(0)[0] == '\0');
|
||||
g_ui->drawOnOffUIElement(UIeDisk2_state, ((AppleVM *)g_vm)->DiskName(1)[0] == '\0');
|
||||
switch (imageIdx) {
|
||||
case IMG_SHELL:
|
||||
drawImageOfSizeAt(shellImage, shellWidth, shellHeight, 0, 0);
|
||||
break;
|
||||
case IMG_D1OPEN:
|
||||
drawImageOfSizeAt(d1OpenImage, driveWidth, driveHeight,
|
||||
use8875 ? 4 : 55,
|
||||
use8875 ? 67 : 216);
|
||||
break;
|
||||
case IMG_D1CLOSED:
|
||||
drawImageOfSizeAt(d1ClosedImage, driveWidth, driveHeight,
|
||||
use8875 ? 4 : 55,
|
||||
use8875 ? 67 : 216);
|
||||
break;
|
||||
case IMG_D2OPEN:
|
||||
drawImageOfSizeAt(d2OpenImage, driveWidth, driveHeight,
|
||||
use8875 ? 4 : 189,
|
||||
use8875 ? 116 : 216);
|
||||
break;
|
||||
case IMG_D2CLOSED:
|
||||
drawImageOfSizeAt(d2ClosedImage, driveWidth, driveHeight,
|
||||
use8875 ? 4 : 189,
|
||||
use8875 ? 116 : 216);
|
||||
break;
|
||||
case IMG_APPLEBATTERY:
|
||||
// FIXME ***
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TeensyDisplay::drawDriveActivity(bool drive0, bool drive1)
|
||||
{
|
||||
// FIXME this could be much more efficient; it's doing a lot of checking use8875 in the middle of a loop
|
||||
|
||||
if (drive0 != driveIndicator[0]) {
|
||||
for (int y=0; y<(use8875 ? LED_HEIGHT_8875 : LED_HEIGHT_9341); y++) {
|
||||
for (int x=0; x<(use8875 ? LED_WIDTH_8875 : LED_WIDTH_9341); x++) {
|
||||
drawPixel(x+(use8875 ? LED1_X_8875 : LED1_X_9341), y+(use8875 ? LED1_Y_8875 : LED1_Y_9341), drive0 ? 0xFA00 : 0x0000);
|
||||
}
|
||||
}
|
||||
driveIndicator[0] = drive0;
|
||||
}
|
||||
|
||||
if (drive1 != driveIndicator[1]) {
|
||||
for (int y=0; y<(use8875 ? LED_HEIGHT_8875 : LED_HEIGHT_9341); y++) {
|
||||
for (int x=0; x<(use8875 ? LED_WIDTH_8875 : LED_WIDTH_9341); x++) {
|
||||
drawPixel(x+(use8875 ? LED2_X_8875 : LED2_X_9341), y+(use8875 ? LED2_Y_8875 : LED2_Y_9341), drive0 ? 0xFA00 : 0x0000);
|
||||
}
|
||||
}
|
||||
|
||||
driveIndicator[1] = drive1;
|
||||
}
|
||||
}
|
||||
|
||||
// *** this probably needs to be private now FIXME
|
||||
void TeensyDisplay::drawImageOfSizeAt(const uint8_t *img,
|
||||
uint16_t sizex, uint16_t sizey,
|
||||
uint16_t wherex, uint16_t wherey)
|
||||
{
|
||||
uint8_t r, g, b;
|
||||
|
||||
// FIXME this needs to scale with TEENSYDISPLAY_SCALE
|
||||
uint8_t *p = img;
|
||||
for (uint16_t y=0; y<sizey; y++) {
|
||||
for (uint16_t x=0; x<sizex; x++) {
|
||||
r = pgm_read_byte(&img[(y*sizex + x)*3 + 0]);
|
||||
g = pgm_read_byte(&img[(y*sizex + x)*3 + 1]);
|
||||
b = pgm_read_byte(&img[(y*sizex + x)*3 + 2]);
|
||||
dmaBuffer[y+wherey][x+wherex] = RGBto565(r,g,b);
|
||||
uint16_t v = pgm_read_byte(p++);
|
||||
v <<= 8;
|
||||
v |= pgm_read_byte(p++);
|
||||
tft->drawPixel(x+wherex, y+wherey, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TeensyDisplay::blit()
|
||||
{
|
||||
// Start DMA transfers if they aren't running
|
||||
if (!tft.asyncUpdateActive())
|
||||
tft.updateScreenAsync(true);
|
||||
if (!tft)
|
||||
return;
|
||||
|
||||
// Start updates, if they're not running already
|
||||
if (!tft->asyncUpdateActive())
|
||||
tft->updateScreenAsync(true);
|
||||
|
||||
static uint32_t ctr = 0;
|
||||
|
||||
// draw overlay, if any, occasionally
|
||||
{
|
||||
static uint32_t nextMessageTime = 0;
|
||||
if (millis() >= nextMessageTime) {
|
||||
if (overlayMessage[0]) {
|
||||
drawString(M_SELECTDISABLED, 1, TEENSYDISPLAY_HEIGHT - (16 + 12)*TEENSYDISPLAY_SCALE, overlayMessage);
|
||||
if (use8875) {
|
||||
drawString(M_SELECTDISABLED, 1, RA8875_HEIGHT-18, overlayMessage);
|
||||
} else {
|
||||
drawString(M_SELECTDISABLED, 1, ILI9341_HEIGHT - (16+12), overlayMessage);
|
||||
}
|
||||
}
|
||||
nextMessageTime = millis() + 10; // DEBUGGING FIXME make 1000 again
|
||||
nextMessageTime = millis() + 1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TeensyDisplay::blit(AiieRect r)
|
||||
{
|
||||
// Nothing to do here, since we're regularly blitting the whole screen via DMA
|
||||
}
|
||||
|
||||
void TeensyDisplay::drawUIPixel(uint16_t x, uint16_t y, uint16_t color)
|
||||
{
|
||||
// These pixels are just cached in the buffer; they're not drawn directly.
|
||||
dmaBuffer[y][x] = color;
|
||||
}
|
||||
|
||||
void TeensyDisplay::drawPixel(uint16_t x, uint16_t y, uint16_t color)
|
||||
{
|
||||
tft.drawPixel(x,y,color);
|
||||
tft->drawPixel(x,y,color);
|
||||
}
|
||||
|
||||
void TeensyDisplay::drawPixel(uint16_t x, uint16_t y, uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
uint16_t color16 = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3);
|
||||
|
||||
drawPixel(x,y,color16);
|
||||
}
|
||||
|
||||
void TeensyDisplay::drawCharacter(uint8_t mode, uint16_t x, uint16_t y, char c)
|
||||
{
|
||||
int8_t xsize = 8,
|
||||
ysize = 0x07;
|
||||
|
||||
uint16_t offPixel, onPixel;
|
||||
switch (mode) {
|
||||
case M_NORMAL:
|
||||
onPixel = 0xFFFF;
|
||||
offPixel = 0x0010;
|
||||
break;
|
||||
case M_SELECTED:
|
||||
onPixel = 0x0000;
|
||||
offPixel = 0xFFFF;
|
||||
break;
|
||||
case M_DISABLED:
|
||||
default:
|
||||
onPixel = 0x7BEF;
|
||||
offPixel = 0x0000;
|
||||
break;
|
||||
case M_SELECTDISABLED:
|
||||
onPixel = 0x7BEF;
|
||||
offPixel = 0xFFE0;
|
||||
break;
|
||||
case M_PLAIN:
|
||||
onPixel = 0xFFFF;
|
||||
offPixel = 0x0000;
|
||||
break;
|
||||
}
|
||||
|
||||
// This does not scale when drawing, because drawPixel scales.
|
||||
const unsigned char *ch = asciiToAppleGlyph(c);
|
||||
for (int8_t y_off = 0; y_off <= ysize; y_off++) {
|
||||
for (int8_t x_off = 0; x_off <= xsize; x_off++) {
|
||||
if (*ch & (1 << (x_off))) {
|
||||
drawUIPixel(x + x_off, y + y_off, onPixel);
|
||||
} else {
|
||||
drawUIPixel(x + x_off, y + y_off, offPixel);
|
||||
}
|
||||
}
|
||||
ch++;
|
||||
}
|
||||
}
|
||||
|
||||
void TeensyDisplay::drawString(uint8_t mode, uint16_t x, uint16_t y, const char *str)
|
||||
{
|
||||
int8_t xsize = 8; // width of a char in this font
|
||||
|
||||
for (int8_t i=0; i<strlen(str); i++) {
|
||||
drawCharacter(mode, x, y, str[i]);
|
||||
x += xsize; // fixme: any inter-char spacing?
|
||||
if (x >= 320) break; // FIXME constant - and pre-scaling, b/c that's in drawCharacter
|
||||
}
|
||||
tft->drawPixel(x,y,color16);
|
||||
}
|
||||
|
||||
void TeensyDisplay::clrScr(uint8_t coloridx)
|
||||
{
|
||||
if (coloridx == c_black) {
|
||||
memset(dmaBuffer, 0x00, sizeof(dmaBuffer));
|
||||
} else if (coloridx == c_white) {
|
||||
memset(dmaBuffer, 0xFF, sizeof(dmaBuffer));
|
||||
} else {
|
||||
uint16_t color16 = loresPixelColors[c_black];
|
||||
if (coloridx < 16)
|
||||
color16 = loresPixelColors[coloridx];
|
||||
// This could be faster - make one line, then memcpy the line to the other
|
||||
// lines?
|
||||
for (uint16_t y=0; y<TEENSYDISPLAY_HEIGHT; y++) {
|
||||
for (uint16_t x=0; x<TEENSYDISPLAY_WIDTH; x++) {
|
||||
dmaBuffer[y][x] = color16;
|
||||
}
|
||||
}
|
||||
}
|
||||
tft->fillWindow(coloridx);
|
||||
}
|
||||
|
||||
inline uint16_t blendColors(uint16_t a, uint16_t b)
|
||||
void TeensyDisplay::cachePixel(uint16_t x, uint16_t y, uint8_t coloridx)
|
||||
{
|
||||
// Straight linear average doesn't work well for inverted text, because the
|
||||
// whites overwhelm the blacks.
|
||||
//return ((uint32_t)a + (uint32_t)b)/2;
|
||||
|
||||
#if 0
|
||||
// Testing a logarithmic color scale. My theory was that, since our
|
||||
// colors here are mostly black or white, it would be reasonable to
|
||||
// use a log scale of the average to bump up the brightness a
|
||||
// little. In practice, it's not really legible.
|
||||
return RGBto565( (uint8_t)(logfn((_565toR(a) + _565toR(b))/2)),
|
||||
(uint8_t)(logfn((_565toG(a) + _565toG(b))/2)),
|
||||
(uint8_t)(logfn((_565toB(a) + _565toB(b))/2)) );
|
||||
#endif
|
||||
|
||||
// Doing an R/G/B average works okay for legibility. It's not great for
|
||||
// inverted text.
|
||||
return RGBto565( (_565toR(a) + _565toR(b))/2,
|
||||
(_565toG(a) + _565toG(b))/2,
|
||||
(_565toB(a) + _565toB(b))/2 );
|
||||
|
||||
}
|
||||
|
||||
// This was called with the expectation that it can draw every one of
|
||||
// the 560x192 pixels that could be addressed. If TEENSYDISPLAY_SCALE
|
||||
// is 1, then we have half of that horizontal resolution - so we need
|
||||
// to be creative and blend neighboring pixels together.
|
||||
void TeensyDisplay::cachePixel(uint16_t x, uint16_t y, uint8_t color)
|
||||
{
|
||||
#if TEENSYDISPLAY_SCALE == 1
|
||||
// This is the case where we need to blend together neighboring
|
||||
// pixels, because we don't have enough physical screen resoultion.
|
||||
if (x&1) {
|
||||
uint16_t origColor = dmaBuffer[y+SCREENINSET_Y][(x>>1)*TEENSYDISPLAY_SCALE+SCREENINSET_X];
|
||||
uint16_t newColor = (uint16_t) loresPixelColors[color];
|
||||
if (g_displayType == m_blackAndWhite) {
|
||||
// There are four reasonable decisions here: if either pixel
|
||||
// *was* on, then it's on; if both pixels *were* on, then it's
|
||||
// on; and if the blended value of the two pixels were on, then
|
||||
// it's on; or if the blended value of the two is above some
|
||||
// certain overall brightness, then it's on. This is the last of
|
||||
// those - where the brightness cutoff is defined in the bios as
|
||||
// g_luminanceCutoff.
|
||||
uint16_t blendedColor = blendColors(origColor, newColor);
|
||||
uint16_t luminance = luminanceFromRGB(_565toR(blendedColor),
|
||||
_565toG(blendedColor),
|
||||
_565toB(blendedColor));
|
||||
cacheDoubleWidePixel(x>>1,y,(uint16_t)((luminance >= g_luminanceCutoff) ? 0xFFFF : 0x0000));
|
||||
} else {
|
||||
cacheDoubleWidePixel(x>>1,y,color);
|
||||
// Else if it's black, we leave whatever was in the other pixel.
|
||||
}
|
||||
} else {
|
||||
// The even pixels always draw.
|
||||
cacheDoubleWidePixel(x>>1,y,color);
|
||||
}
|
||||
#else
|
||||
// we have enough resolution to show all the pixels, so just do it
|
||||
x = (x * TEENSYDISPLAY_SCALE)/2;
|
||||
for (int yoff=0; yoff<TEENSYDISPLAY_SCALE; yoff++) {
|
||||
for (int xoff=0; xoff<TEENSYDISPLAY_SCALE; xoff++) {
|
||||
dmaBuffer[y*TEENSYDISPLAY_SCALE+yoff+SCREENINSET_Y][x+xoff+SCREENINSET_X] = color;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void TeensyDisplay::cacheDoubleWidePixel(uint16_t x, uint16_t y, uint16_t color16)
|
||||
{
|
||||
for (int yoff=0; yoff<TEENSYDISPLAY_SCALE; yoff++) {
|
||||
for (int xoff=0; xoff<TEENSYDISPLAY_SCALE; xoff++) {
|
||||
dmaBuffer[(y*TEENSYDISPLAY_SCALE+yoff+SCREENINSET_Y)][x*TEENSYDISPLAY_SCALE+xoff+SCREENINSET_X] = color16;
|
||||
}
|
||||
}
|
||||
tft->cacheApplePixel(x,y,coloridx);
|
||||
}
|
||||
|
||||
// "DoubleWide" means "please double the X because I'm in low-res
|
||||
// width mode".
|
||||
void TeensyDisplay::cacheDoubleWidePixel(uint16_t x, uint16_t y, uint8_t color)
|
||||
void TeensyDisplay::cacheDoubleWidePixel(uint16_t x, uint16_t y, uint8_t coloridx)
|
||||
{
|
||||
uint16_t color16;
|
||||
color16 = loresPixelColors[(( color & 0x0F ) )];
|
||||
|
||||
for (int yoff=0; yoff<TEENSYDISPLAY_SCALE; yoff++) {
|
||||
for (int xoff=0; xoff<TEENSYDISPLAY_SCALE; xoff++) {
|
||||
dmaBuffer[(y*TEENSYDISPLAY_SCALE+yoff+SCREENINSET_Y)][x*TEENSYDISPLAY_SCALE+xoff+SCREENINSET_X] = color16;
|
||||
}
|
||||
}
|
||||
tft->cacheDoubleWideApplePixel(x, y, coloridx);
|
||||
}
|
||||
|
||||
// This exists for 4bpp optimization. We could totally call
|
||||
// cacheDoubleWidePixel twice, but the (x&1) pfutzing is messy if
|
||||
// we're just storing both halves anyway...
|
||||
void TeensyDisplay::cache2DoubleWidePixels(uint16_t x, uint16_t y,
|
||||
uint8_t colorA, uint8_t colorB)
|
||||
{
|
||||
for (int yoff=0; yoff<TEENSYDISPLAY_SCALE; yoff++) {
|
||||
for (int xoff=0; xoff<TEENSYDISPLAY_SCALE; xoff++) {
|
||||
dmaBuffer[(y*TEENSYDISPLAY_SCALE+yoff+SCREENINSET_Y)][x*TEENSYDISPLAY_SCALE+2*xoff+SCREENINSET_X] = loresPixelColors[colorA];
|
||||
dmaBuffer[(y*TEENSYDISPLAY_SCALE+yoff+SCREENINSET_Y)][x*TEENSYDISPLAY_SCALE+1+2*xoff+SCREENINSET_X] = loresPixelColors[colorB];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline double logfn(double x)
|
||||
{
|
||||
// At a value of x=255, log(base 1.022)(x) is 254.636.
|
||||
return log(x)/log(1.022);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32_t TeensyDisplay::frameCount()
|
||||
{
|
||||
return tft.frameCount();
|
||||
if (!tft)
|
||||
return 0;
|
||||
|
||||
return tft->frameCount();
|
||||
}
|
||||
|
|
|
@ -2,16 +2,13 @@
|
|||
#define __TEENSY_DISPLAY_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <ILI9341_t3n.h>
|
||||
#include <SPI.h>
|
||||
#include "basedisplay.h"
|
||||
|
||||
#include "physicaldisplay.h"
|
||||
|
||||
class BIOS;
|
||||
|
||||
#define TEENSYDISPLAY_SCALE 1
|
||||
#define TEENSYDISPLAY_WIDTH (320*TEENSYDISPLAY_SCALE)
|
||||
#define TEENSYDISPLAY_HEIGHT (240*TEENSYDISPLAY_SCALE)
|
||||
|
||||
class TeensyDisplay : public PhysicalDisplay {
|
||||
friend class BIOS;
|
||||
|
||||
|
@ -20,31 +17,39 @@ class TeensyDisplay : public PhysicalDisplay {
|
|||
virtual ~TeensyDisplay();
|
||||
|
||||
virtual void blit();
|
||||
virtual void blit(AiieRect r);
|
||||
virtual void redraw();
|
||||
virtual void flush() { };
|
||||
|
||||
virtual void clrScr(uint8_t coloridx);
|
||||
virtual void flush();
|
||||
|
||||
virtual void drawCharacter(uint8_t mode, uint16_t x, uint16_t y, char c);
|
||||
virtual void drawString(uint8_t mode, uint16_t x, uint16_t y, const char *str);
|
||||
virtual void drawUIImage(uint8_t imageIdx);
|
||||
virtual void drawDriveActivity(bool drive0, bool drive1);
|
||||
|
||||
virtual void drawImageOfSizeAt(const uint8_t *img, uint16_t sizex, uint16_t sizey, uint16_t wherex, uint16_t wherey);
|
||||
|
||||
void cacheDoubleWidePixel(uint16_t x, uint16_t y, uint16_t color16);
|
||||
virtual void cacheDoubleWidePixel(uint16_t x, uint16_t y, uint8_t color);
|
||||
virtual void cache2DoubleWidePixels(uint16_t x, uint16_t y, uint8_t colorA, uint8_t colorB);
|
||||
virtual void cachePixel(uint16_t x, uint16_t y, uint8_t color);
|
||||
|
||||
uint32_t frameCount();
|
||||
private:
|
||||
virtual void drawPixel(uint16_t x, uint16_t y, uint16_t color);
|
||||
virtual void drawPixel(uint16_t x, uint16_t y, uint8_t r, uint8_t g, uint8_t b);
|
||||
virtual void drawUIPixel(uint16_t x, uint16_t y, uint16_t color);
|
||||
|
||||
bool needsRedraw;
|
||||
bool driveIndicator[2];
|
||||
bool driveIndicatorDirty;
|
||||
|
||||
private:
|
||||
const uint8_t *shellImage;
|
||||
const uint16_t shellWidth, shellHeight;
|
||||
const uint8_t *d1OpenImage;
|
||||
const uint16_t driveWidth, driveHeight; // assume all the latches are the same width/height no matter what position
|
||||
const uint8_t *d1ClosedImage;
|
||||
const uint8_t *d2OpenImage;
|
||||
const uint8_t *d2ClosedImage;
|
||||
const uint8_t *appleImage;
|
||||
const uint16_t appleImageWidth, appleImageHeight;
|
||||
|
||||
bool use8875;
|
||||
|
||||
BaseDisplay *tft;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -115,8 +115,6 @@ int16_t TeensyFileManager::readDir(const char *where, const char *suffix, char *
|
|||
while (e.openNext(&outerDir, O_RDONLY)) {
|
||||
|
||||
// Skip MAC fork files
|
||||
// FIXME: strncpy
|
||||
strcpy(outputFN, e.name()); // and we need maxlen-1 for trailing '/' on directories
|
||||
e.getName(outputFN, maxlen-1); // -1 for trailing '/' on directories
|
||||
|
||||
if (outputFN[0] == '.') {
|
||||
|
@ -240,7 +238,7 @@ int TeensyFileManager::write(int8_t fd, const void *buf, int nbyte)
|
|||
uint32_t pos = fileSeekPositions[fd];
|
||||
|
||||
if (!cacheFile.seek(pos)) {
|
||||
printf("can't seek to %d\n", pos);
|
||||
printf("can't seek to %d\n", (int)pos);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ AudioConnection patchCord4(mixer1, 0, i2s, 0);
|
|||
|
||||
// Ring buffer that we fill with 44.1kHz data
|
||||
#define BUFSIZE (4096)
|
||||
#define CACHEMULTIPLIER 2
|
||||
#define CACHEMULTIPLIER 10
|
||||
static volatile uint32_t bufIdx; // 0 .. BUFSIZE-1
|
||||
static volatile uint64_t skippedSamples; // Who knows where this will
|
||||
// wind up
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#define BATTERYSELECT 21 // digital select that turns on the power reading ckt
|
||||
|
||||
#include "globals.h"
|
||||
#include "teensy-crash.h"
|
||||
|
||||
BIOS bios;
|
||||
|
||||
|
@ -166,6 +165,10 @@ void setup()
|
|||
delay(2000);
|
||||
#endif
|
||||
delay(200); // let the power settle & serial to get its bearings
|
||||
if (CrashReport) {
|
||||
Serial.print(CrashReport);
|
||||
delay(5000);
|
||||
}
|
||||
|
||||
pinMode(DEBUGPIN, OUTPUT); // for debugging
|
||||
pinMode(BATTERYSELECT, OUTPUT);
|
||||
|
@ -355,6 +358,7 @@ void runDisplay(uint32_t now)
|
|||
}
|
||||
|
||||
if (!g_biosInterrupt) {
|
||||
// FIXME this needs some love. It could be efficient, but parts are removed, so it's doing duplicative work.
|
||||
g_ui->blit();
|
||||
g_vm->vmdisplay->lockDisplay();
|
||||
if (g_vm->vmdisplay->needsRedraw()) { // necessary for the VM to redraw
|
||||
|
|
|
@ -0,0 +1,211 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define _565To332(c) ((((c) & 0xe000) >> 8) | (((c) & 0x700) >> 6) | (((c) & 0x18) >> 3))
|
||||
|
||||
|
||||
static void rgb_to_hsv(double r, double g, double b, double *h, double *s, double *v)
|
||||
{
|
||||
// Range for these equations is [0..1] not [0..255]
|
||||
r = r / 255.0;
|
||||
g = g / 255.0;
|
||||
b = b / 255.0;
|
||||
|
||||
// h, s, v = hue, saturation, value
|
||||
double cmax = max(r, max(g, b)); // maximum of r, g, b
|
||||
double cmin = min(r, min(g, b)); // minimum of r, g, b
|
||||
double diff = cmax - cmin; // diff of cmax and cmin.
|
||||
|
||||
// if cmax and cmax are equal then h = 0
|
||||
if (cmax == cmin)
|
||||
*h = 0;
|
||||
|
||||
// if cmax equal r then compute h
|
||||
else if (cmax == r)
|
||||
*h = (int)(60 * ((g - b) / diff) + 360) % 360;
|
||||
|
||||
// if cmax equal g then compute h
|
||||
else if (cmax == g)
|
||||
*h = (int)(60 * ((b - r) / diff) + 120) % 360;
|
||||
|
||||
// if cmax equal b then compute h
|
||||
else if (cmax == b)
|
||||
*h = (int)(60 * ((r - g) / diff) + 240) % 360;
|
||||
|
||||
// if cmax equal zero
|
||||
if (cmax == 0)
|
||||
*s = 0;
|
||||
else
|
||||
*s = (diff / cmax) * 100;
|
||||
|
||||
// compute v
|
||||
*v = cmax * 100;
|
||||
}
|
||||
|
||||
static void hsv_to_rgb(double H, double S, double V, uint8_t *R, uint8_t *G, uint8_t *B)
|
||||
{
|
||||
float s = S/100;
|
||||
float v = V/100;
|
||||
float C = s*v;
|
||||
float X = C*(1-fabs(fmod(H/60.0, 2)-1));
|
||||
float m = v-C;
|
||||
float r,g,b;
|
||||
if(H >= 0 && H < 60){
|
||||
r = C,g = X,b = 0;
|
||||
}
|
||||
else if(H >= 60 && H < 120){
|
||||
r = X,g = C,b = 0;
|
||||
}
|
||||
else if(H >= 120 && H < 180){
|
||||
r = 0,g = C,b = X;
|
||||
}
|
||||
else if(H >= 180 && H < 240){
|
||||
r = 0,g = X,b = C;
|
||||
}
|
||||
else if(H >= 240 && H < 300){
|
||||
r = X,g = 0,b = C;
|
||||
}
|
||||
else{
|
||||
r = C,g = 0,b = X;
|
||||
}
|
||||
*R = (r+m)*255;
|
||||
*G = (g+m)*255;
|
||||
*B = (b+m)*255;
|
||||
}
|
||||
|
||||
// blend two 24-bit packed colors
|
||||
uint32_t blendColors(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint8_t r1, r2, g1, g2, b1, b2;
|
||||
r1 = (a & 0xFF0000) >> 16;
|
||||
g1 = (a & 0x00FF00) >> 8;
|
||||
b1 = (a & 0x0000FF);
|
||||
r2 = (b & 0xFF0000) >> 16;
|
||||
g2 = (b & 0x00FF00) >> 8;
|
||||
b2 = (b & 0x0000FF);
|
||||
|
||||
double h1, s1, v1, h2, s2, v2;
|
||||
rgb_to_hsv(r1, g1, b1, &h1, &s1, &v1);
|
||||
rgb_to_hsv(r2, g2, b2, &h2, &s2, &v2);
|
||||
|
||||
hsv_to_rgb((h1+h2)/2, (s1+s2)/2, (v1+v2)/2, &r1, &g1, &b1);
|
||||
uint32_t ret = (r1 << 16) | (g1 << 8) | (b1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// RGB map of each of the lowres colors
|
||||
const uint8_t loresPixelColors[16][3] = { { 0, 0, 0 }, // black
|
||||
{ 0xAC, 0x12, 0x4C }, // magenta
|
||||
{ 0x00, 0x07, 0x83 }, // dark blue
|
||||
{ 0xAA, 0x1A, 0xD1 }, // purple
|
||||
{ 0x00, 0x83, 0x2F }, // dark green
|
||||
{ 0x9F, 0x97, 0x7E }, // drak grey
|
||||
{ 0x00, 0x8A, 0xB5 }, // medium blue
|
||||
{ 0x9F, 0x9E, 0xFF }, // light blue
|
||||
{ 0x7A, 0x5F, 0x00 }, // brown
|
||||
{ 0xFF, 0x72, 0x47 }, // orange
|
||||
{ 0x78, 0x68, 0x7F }, // light gray
|
||||
{ 0xFF, 0x7A, 0xCF }, // pink
|
||||
{ 0x6F, 0xE6, 0x2C }, // green
|
||||
{ 0xFF, 0xF6, 0x7B }, // yellow
|
||||
{ 0x6C, 0xEE, 0xB2 }, // aqua
|
||||
{ 0xFF, 0xFF, 0xFF } // white
|
||||
};
|
||||
|
||||
static const uint16_t palette16[16] = {
|
||||
0x0000, // 0 black
|
||||
0xC006, // 1 magenta
|
||||
0x0010, // 2 dark blue
|
||||
0xA1B5, // 3 purple
|
||||
0x0480, // 4 dark green
|
||||
0x6B4D, // 5 dark grey
|
||||
0x1B9F, // 6 med blue
|
||||
0x0DFD, // 7 light blue
|
||||
0x92A5, // 8 brown
|
||||
0xF8C5, // 9 orange
|
||||
0x9555, // 10 light gray
|
||||
0xFCF2, // 11 pink
|
||||
0x07E0, // 12 green
|
||||
0xFFE0, // 13 yellow
|
||||
0x87F0, // 14 aqua
|
||||
0xFFFF // 15 white
|
||||
};
|
||||
|
||||
#define color16To32(x) ( (((x) & 0xF800) << 8) | (((x) & 0x07E0) << 5) | (((x) & 0x001F)<<3) )
|
||||
#define packColor32(x) ( (x[0] << 16) | (x[1] << 8) | (x[2]) )
|
||||
#define unpackRed(x) ( ((x) & 0xFF0000) >> 16 )
|
||||
#define unpackGreen(x) ( ((x) & 0xFF00) >> 8 )
|
||||
#define unpackBlue(x) ( ((x) & 0xFF) )
|
||||
// FIXME this blend could be optimized - and it's a dumb blend that
|
||||
// just averages RGB values individually, rather than trying to find a
|
||||
// sane blend of 2 pixels. Needs thought.
|
||||
#define luminanceFromRGB(r,g,b) ( ((r)*0.2126) + ((g)*0.7152) + ((b)*0.0722) )
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
for (int i=0; i<16; i++) {
|
||||
printf("color %d: 32-bit 0x%.8X 16-bit 0x%.4X 8-bit 0x%.2X\n",
|
||||
i,
|
||||
packColor32(loresPixelColors[i]),
|
||||
palette16[i],
|
||||
_565To332(palette16[i]));
|
||||
|
||||
}
|
||||
|
||||
uint32_t mix32[16][16];
|
||||
uint16_t mix16[16][16];
|
||||
uint8_t mix8[16][16];
|
||||
|
||||
for (int a=0; a<16; a++) {
|
||||
for (int b=0; b<16; b++) {
|
||||
uint32_t v = blendColors(packColor32(loresPixelColors[a]),
|
||||
packColor32(loresPixelColors[b]));
|
||||
uint16_t v16 = ((unpackRed(v) & 0xF8) << 8) |
|
||||
((unpackGreen(v) & 0xFC) << 3) |
|
||||
((unpackBlue(v) & 0xF8) >> 3);
|
||||
uint8_t v8 = _565To332(v16);
|
||||
mix32[a][b] = v;
|
||||
mix16[a][b] = v16;
|
||||
mix8[a][b] = v8;
|
||||
}
|
||||
}
|
||||
|
||||
printf("uint8_t mix8[16][16] = {\n");
|
||||
for (int a=0; a<16; a++) {
|
||||
for (int b=0; b<16; b++) {
|
||||
printf("0x%.2X, ", mix8[a][b]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("};\n\n");
|
||||
|
||||
printf("uint16_t mix16[16][16] = {\n");
|
||||
for (int a=0; a<16; a++) {
|
||||
for (int b=0; b<16; b++) {
|
||||
printf("0x%.4X, ", mix16[a][b]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("};\n\n");
|
||||
|
||||
printf("uint32_t mix32[16][16] = {\n");
|
||||
for (int a=0; a<16; a++) {
|
||||
for (int b=0; b<16; b++) {
|
||||
printf("0x%.8X, ", mix32[a][b]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("};\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
#expects RGB 24-bit data
|
||||
|
||||
my $infile = shift || die "give me a file name, with raw bytes in it";
|
||||
my $size = (-s $infile);
|
||||
|
||||
open my $fh, '<', $infile || die $!;
|
||||
|
||||
my $count = 0;
|
||||
my ($bufr, $bufg, $bufb);
|
||||
while (my $r = read $fh, $bufr, 1) {
|
||||
my $g = read $fh, $bufg, 1;
|
||||
my $b = read $fh, $bufb, 1;
|
||||
|
||||
my $v16 =
|
||||
((ord($bufr)&0xF8) << 8) |
|
||||
((ord($bufg)&0xFC) << 3) |
|
||||
( ord($bufb) >> 3);
|
||||
|
||||
printf("0x%.2X,0x%.2X, ", ($v16 >> 8), $v16 & 0xFF);
|
||||
|
||||
if (++$count == 8) {
|
||||
print "\n";
|
||||
$count = 0;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
Loading…
Reference in New Issue