mirror of https://github.com/JorjBauer/aiie.git
add luminance cutoff for B&W mode
This commit is contained in:
parent
efc36d40a8
commit
97059a0a5b
60
bios.cpp
60
bios.cpp
|
@ -60,20 +60,22 @@ enum {
|
||||||
ACT_REBOOTANDEJECT = 4,
|
ACT_REBOOTANDEJECT = 4,
|
||||||
ACT_MONITOR = 5,
|
ACT_MONITOR = 5,
|
||||||
ACT_DISPLAYTYPE = 6,
|
ACT_DISPLAYTYPE = 6,
|
||||||
ACT_DEBUG = 7,
|
ACT_LUMINANCEUP = 7,
|
||||||
ACT_DISK1 = 8,
|
ACT_LUMINANCEDOWN = 8,
|
||||||
ACT_DISK2 = 9,
|
ACT_DEBUG = 9,
|
||||||
ACT_HD1 = 10,
|
ACT_DISK1 = 10,
|
||||||
ACT_HD2 = 11,
|
ACT_DISK2 = 11,
|
||||||
ACT_VOLPLUS = 12,
|
ACT_HD1 = 12,
|
||||||
ACT_VOLMINUS = 13,
|
ACT_HD2 = 13,
|
||||||
ACT_SUSPEND = 14,
|
ACT_VOLPLUS = 14,
|
||||||
ACT_RESTORE = 15,
|
ACT_VOLMINUS = 15,
|
||||||
ACT_PADX_INV = 16,
|
ACT_SUSPEND = 16,
|
||||||
ACT_PADY_INV = 17,
|
ACT_RESTORE = 17,
|
||||||
ACT_PADDLES = 18,
|
ACT_PADX_INV = 18,
|
||||||
ACT_SPEED = 19,
|
ACT_PADY_INV = 19,
|
||||||
ACT_ABOUT = 20,
|
ACT_PADDLES = 20,
|
||||||
|
ACT_SPEED = 21,
|
||||||
|
ACT_ABOUT = 22,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_TITLES 4
|
#define NUM_TITLES 4
|
||||||
|
@ -85,7 +87,8 @@ const uint8_t aiieActions[] = { ACT_ABOUT };
|
||||||
const uint8_t vmActions[] = { ACT_EXIT, ACT_RESET, ACT_REBOOT, ACT_REBOOTANDEJECT,
|
const uint8_t vmActions[] = { ACT_EXIT, ACT_RESET, ACT_REBOOT, ACT_REBOOTANDEJECT,
|
||||||
ACT_MONITOR,
|
ACT_MONITOR,
|
||||||
ACT_DEBUG, ACT_SUSPEND, ACT_RESTORE };
|
ACT_DEBUG, ACT_SUSPEND, ACT_RESTORE };
|
||||||
const uint8_t hardwareActions[] = { ACT_DISPLAYTYPE, ACT_SPEED,
|
const uint8_t hardwareActions[] = { ACT_DISPLAYTYPE, ACT_LUMINANCEUP,
|
||||||
|
ACT_LUMINANCEDOWN, ACT_SPEED,
|
||||||
ACT_PADX_INV, ACT_PADY_INV,
|
ACT_PADX_INV, ACT_PADY_INV,
|
||||||
ACT_PADDLES, ACT_VOLPLUS, ACT_VOLMINUS };
|
ACT_PADDLES, ACT_VOLPLUS, ACT_VOLMINUS };
|
||||||
const uint8_t diskActions[] = { ACT_DISK1, ACT_DISK2,
|
const uint8_t diskActions[] = { ACT_DISK1, ACT_DISK2,
|
||||||
|
@ -386,6 +389,20 @@ uint16_t BIOS::HardwareMenuHandler(bool needsRedraw, bool performAction)
|
||||||
((AppleDisplay*)g_display)->displayTypeChanged();
|
((AppleDisplay*)g_display)->displayTypeChanged();
|
||||||
localRedraw = true;
|
localRedraw = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ACT_LUMINANCEUP:
|
||||||
|
if (g_luminanceCutoff < 255)
|
||||||
|
g_luminanceCutoff++;
|
||||||
|
((AppleDisplay*)g_display)->displayTypeChanged();
|
||||||
|
localRedraw = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACT_LUMINANCEDOWN:
|
||||||
|
if (g_luminanceCutoff > 0)
|
||||||
|
g_luminanceCutoff--;
|
||||||
|
((AppleDisplay*)g_display)->displayTypeChanged();
|
||||||
|
localRedraw = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case ACT_SPEED:
|
case ACT_SPEED:
|
||||||
currentCPUSpeedIndex++;
|
currentCPUSpeedIndex++;
|
||||||
|
@ -797,6 +814,11 @@ bool BIOS::isActionActive(int8_t action)
|
||||||
case ACT_PADDLES:
|
case ACT_PADDLES:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case ACT_LUMINANCEUP:
|
||||||
|
return (g_luminanceCutoff < 255);
|
||||||
|
case ACT_LUMINANCEDOWN:
|
||||||
|
return (g_luminanceCutoff > 0);
|
||||||
|
|
||||||
case ACT_VOLPLUS:
|
case ACT_VOLPLUS:
|
||||||
return (g_volume < 15);
|
return (g_volume < 15);
|
||||||
case ACT_VOLMINUS:
|
case ACT_VOLMINUS:
|
||||||
|
@ -934,6 +956,14 @@ void BIOS::DrawHardwareMenu()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ACT_LUMINANCEUP:
|
||||||
|
sprintf(buf, "Luminance+: %d", g_luminanceCutoff);
|
||||||
|
break;
|
||||||
|
case ACT_LUMINANCEDOWN:
|
||||||
|
sprintf(buf, "Luminance-: %d", g_luminanceCutoff);
|
||||||
|
break;
|
||||||
|
|
||||||
case ACT_SPEED:
|
case ACT_SPEED:
|
||||||
{
|
{
|
||||||
const char *templateString = "CPU Speed: %s";
|
const char *templateString = "CPU Speed: %s";
|
||||||
|
|
|
@ -10,7 +10,7 @@ PhysicalSpeaker *g_speaker = NULL;
|
||||||
PhysicalPaddles *g_paddles = NULL;
|
PhysicalPaddles *g_paddles = NULL;
|
||||||
PhysicalPrinter *g_printer = NULL;
|
PhysicalPrinter *g_printer = NULL;
|
||||||
VMui *g_ui;
|
VMui *g_ui;
|
||||||
int8_t g_volume = 15;
|
int8_t g_volume = 7;
|
||||||
uint8_t g_displayType = 3; // FIXME m_perfectcolor
|
uint8_t g_displayType = 3; // FIXME m_perfectcolor
|
||||||
VMRam g_ram;
|
VMRam g_ram;
|
||||||
volatile uint8_t g_debugMode = D_NONE;
|
volatile uint8_t g_debugMode = D_NONE;
|
||||||
|
@ -19,6 +19,8 @@ uint32_t g_speed = 1023000; // Hz
|
||||||
bool g_invertPaddleX = false;
|
bool g_invertPaddleX = false;
|
||||||
bool g_invertPaddleY = false;
|
bool g_invertPaddleY = false;
|
||||||
|
|
||||||
|
uint8_t g_luminanceCutoff = 122; // reasonable values are 127 and 128 for 32-bit (SDL); and 122/123 for 16-bit (teensy) depending on whether we're talking about white-on-black or black-on-white
|
||||||
|
|
||||||
char debugBuf[255];
|
char debugBuf[255];
|
||||||
|
|
||||||
#ifdef TEENSYDUINO
|
#ifdef TEENSYDUINO
|
||||||
|
|
|
@ -56,6 +56,8 @@ extern uint32_t g_speed;
|
||||||
extern bool g_invertPaddleX;
|
extern bool g_invertPaddleX;
|
||||||
extern bool g_invertPaddleY;
|
extern bool g_invertPaddleY;
|
||||||
|
|
||||||
|
extern uint8_t g_luminanceCutoff;
|
||||||
|
|
||||||
extern char debugBuf[255];
|
extern char debugBuf[255];
|
||||||
|
|
||||||
#ifdef TEENSYDUINO
|
#ifdef TEENSYDUINO
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
// Fun trivia: the Apple //e was in production from January 1983 to
|
// Fun trivia: the Apple //e was in production from January 1983 to
|
||||||
// November 1993. And the 65C02 in them supported weird BCD math modes.
|
// November 1993. And the 65C02 in them supported weird BCD math modes.
|
||||||
#define PREFSMAGIC 0x01831093
|
#define PREFSMAGIC 0x01831093
|
||||||
#define PREFSVERSION 3
|
#define PREFSVERSION 4
|
||||||
|
|
||||||
#ifndef MAXPATH
|
#ifndef MAXPATH
|
||||||
#define MAXPATH 255
|
#define MAXPATH 255
|
||||||
|
@ -21,6 +21,8 @@ typedef struct _prefs {
|
||||||
|
|
||||||
uint8_t volume;
|
uint8_t volume;
|
||||||
uint8_t displayType;
|
uint8_t displayType;
|
||||||
|
uint8_t luminanceCutoff;
|
||||||
|
|
||||||
uint8_t debug;
|
uint8_t debug;
|
||||||
uint8_t speed;
|
uint8_t speed;
|
||||||
|
|
||||||
|
@ -33,6 +35,8 @@ typedef struct _prefs {
|
||||||
char disk2[MAXPATH];
|
char disk2[MAXPATH];
|
||||||
char hd1[MAXPATH];
|
char hd1[MAXPATH];
|
||||||
char hd2[MAXPATH];
|
char hd2[MAXPATH];
|
||||||
|
|
||||||
|
uint32_t magicFooter;
|
||||||
} prefs_t;
|
} prefs_t;
|
||||||
|
|
||||||
class PrefsStore {
|
class PrefsStore {
|
||||||
|
|
|
@ -451,6 +451,8 @@ void readPrefs()
|
||||||
if (np.readPrefs(&p)) {
|
if (np.readPrefs(&p)) {
|
||||||
g_volume = p.volume;
|
g_volume = p.volume;
|
||||||
g_displayType = p.displayType;
|
g_displayType = p.displayType;
|
||||||
|
g_luminanceCutoff = p.luminanceCutoff;
|
||||||
|
|
||||||
g_debugMode = p.debug;
|
g_debugMode = p.debug;
|
||||||
g_speed = (p.speed * (1023000/2)); // steps of half normal speed
|
g_speed = (p.speed * (1023000/2)); // steps of half normal speed
|
||||||
if (g_speed < (1023000/2))
|
if (g_speed < (1023000/2))
|
||||||
|
@ -484,7 +486,10 @@ void writePrefs()
|
||||||
p.version = PREFSVERSION;
|
p.version = PREFSVERSION;
|
||||||
|
|
||||||
p.volume = g_volume;
|
p.volume = g_volume;
|
||||||
|
|
||||||
p.displayType = g_displayType;
|
p.displayType = g_displayType;
|
||||||
|
p.luminanceCutoff = g_luminanceCutoff;
|
||||||
|
|
||||||
p.debug = g_debugMode;
|
p.debug = g_debugMode;
|
||||||
p.speed = g_speed / (1023000/2);
|
p.speed = g_speed / (1023000/2);
|
||||||
strcpy(p.disk1, ((AppleVM *)g_vm)->DiskName(0));
|
strcpy(p.disk1, ((AppleVM *)g_vm)->DiskName(0));
|
||||||
|
|
|
@ -39,10 +39,14 @@ const uint8_t loresPixelColors[16][3] = { { 0, 0, 0 }, // black
|
||||||
|
|
||||||
#define color16To32(x) ( (((x) & 0xF800) << 8) | (((x) & 0x07E0) << 5) | (((x) & 0x001F)<<3) )
|
#define color16To32(x) ( (((x) & 0xF800) << 8) | (((x) & 0x07E0) << 5) | (((x) & 0x001F)<<3) )
|
||||||
#define packColor32(x) ( (x[0] << 16) | (x[1] << 8) | (x[2]) )
|
#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
|
// FIXME this blend could be optimized - and it's a dumb blend that
|
||||||
// just averages RGB values individually, rather than trying to find a
|
// just averages RGB values individually, rather than trying to find a
|
||||||
// sane blend of 2 pixels. Needs thought.
|
// sane blend of 2 pixels. Needs thought.
|
||||||
#define blendPackedColor(x,y) ( (((x) & 0xFF0000) + ((y) & 0xFF0000) / 2) + (((x) & 0x00FF00) + ((y) & 0x00FF00)) / 2 + (((x) & 0x0000FF) + ((y) & 0x0000FF)) / 2 )
|
#define blendPackedColor(x,y) ( (((unpackRed(x) + unpackRed(y))/2) << 16) + (((unpackGreen(x) + unpackGreen(y))/2) << 8) + ((unpackBlue(x) + unpackBlue(y))/2) )
|
||||||
|
#define luminanceFromRGB(r,g,b) ( ((r)*0.2126) + ((g)*0.7152) + ((b)*0.0722) )
|
||||||
|
|
||||||
SDLDisplay::SDLDisplay()
|
SDLDisplay::SDLDisplay()
|
||||||
{
|
{
|
||||||
|
@ -128,9 +132,9 @@ void SDLDisplay::blit(AiieRect r)
|
||||||
b = (colorIdx & 0x0000FF);
|
b = (colorIdx & 0x0000FF);
|
||||||
|
|
||||||
if (g_displayType == m_monochrome) {
|
if (g_displayType == m_monochrome) {
|
||||||
float fv = 0.2125 * r + 0.7154 * g + 0.0721 * b;
|
// float fv = 0.2125 * r + 0.7154 * g + 0.0721 * b;
|
||||||
r = b = 0;
|
// r = b = 0;
|
||||||
g = fv;
|
// g = fv;
|
||||||
}
|
}
|
||||||
else if (g_displayType == m_blackAndWhite) {
|
else if (g_displayType == m_blackAndWhite) {
|
||||||
// Used to reduce to B&W in this driver, but now it's up in the apple display
|
// Used to reduce to B&W in this driver, but now it's up in the apple display
|
||||||
|
@ -263,23 +267,32 @@ void SDLDisplay::clrScr(uint8_t coloridx)
|
||||||
SDL_RenderPresent(renderer); // perform the render
|
SDL_RenderPresent(renderer); // perform the render
|
||||||
}
|
}
|
||||||
|
|
||||||
// This was called with the expectation that it can draw every one of
|
// This was called with the expectation that it can draw every one of
|
||||||
// the 560x192 pixels that could be addressed. If TEENSYDISPLAY_SCALE
|
// the 560x192 pixels that could be addressed. If TEENSYDISPLAY_SCALE
|
||||||
// is 1, then we have half of that horizontal resolution - so we need
|
// is 1, then we have half of that horizontal resolution - so we need
|
||||||
// to be creative and blend neighboring pixels together.
|
// to be creative and blend neighboring pixels together.
|
||||||
void SDLDisplay::cachePixel(uint16_t x, uint16_t y, uint8_t color)
|
void SDLDisplay::cachePixel(uint16_t x, uint16_t y, uint8_t color)
|
||||||
{
|
{
|
||||||
#if SDLDISPLAY_SCALE == 1
|
#if SDLDISPLAY_SCALE == 1
|
||||||
// This is the case where we need to blend together neighboring
|
// This is the case where we need to blend together neighboring
|
||||||
// pixels, because we don't have enough physical screen resoultion.
|
// pixels, because we don't have enough physical screen resoultion.
|
||||||
|
|
||||||
if (x&1) {
|
if (x&1) {
|
||||||
uint32_t origColor = videoBuffer[y][(x>>1)*SDLDISPLAY_SCALE];
|
uint32_t origColor = videoBuffer[y][(x>>1)*SDLDISPLAY_SCALE];
|
||||||
uint32_t newColor = packColor32(loresPixelColors[color]);
|
uint32_t newColor = packColor32(loresPixelColors[color]);
|
||||||
if (g_displayType == m_blackAndWhite) {
|
if (g_displayType == m_blackAndWhite) {
|
||||||
// FIXME: the two possible sets here of 'origColor && newColor' or 'origColor||newColor'
|
// There are four reasonable decisions here: if either pixel
|
||||||
// work well for black-on-white and white-on-black. But neither is good in the other.
|
// *was* on, then it's on; if both pixels *were* on, then it's
|
||||||
cacheDoubleWidePixel(x>>1,y,(uint32_t)((origColor && newColor) ? 0xFFFFFF : 0x000000));
|
// 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 {
|
} else {
|
||||||
cacheDoubleWidePixel(x>>1,y,(uint32_t)blendPackedColor(origColor, newColor));
|
cacheDoubleWidePixel(x>>1,y,(uint32_t)blendPackedColor(origColor, newColor));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <DMAChannel.h>
|
#include <DMAChannel.h>
|
||||||
|
|
||||||
#include "teensy-display.h"
|
#include "teensy-display.h"
|
||||||
|
#include "iocompat.h"
|
||||||
|
|
||||||
#include "appleui.h"
|
#include "appleui.h"
|
||||||
// FIXME should be able to omit this include and rely on the xterns, which
|
// FIXME should be able to omit this include and rely on the xterns, which
|
||||||
|
@ -54,8 +55,10 @@ DMAMEM uint16_t dmaBuffer[TEENSYDISPLAY_HEIGHT][TEENSYDISPLAY_WIDTH];
|
||||||
|
|
||||||
#define RGBto565(r,g,b) ((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | ((b) >> 3))
|
#define RGBto565(r,g,b) ((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | ((b) >> 3))
|
||||||
#define _565toR(c) ( ((c) & 0xF800) >> 8 )
|
#define _565toR(c) ( ((c) & 0xF800) >> 8 )
|
||||||
#define _565toG(c) ( ((c) & 0x07E0) >> 5 )
|
#define _565toG(c) ( ((c) & 0x07E0) >> 3 )
|
||||||
#define _565toB(c) ( ((c) & 0x001F) )
|
#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);
|
ILI9341_t3n tft = ILI9341_t3n(PIN_CS, PIN_DC, PIN_RST, PIN_MOSI, PIN_SCK, PIN_MISO);
|
||||||
|
|
||||||
|
@ -125,7 +128,7 @@ void TeensyDisplay::blit()
|
||||||
if (overlayMessage[0]) {
|
if (overlayMessage[0]) {
|
||||||
drawString(M_SELECTDISABLED, 1, TEENSYDISPLAY_HEIGHT - (16 + 12)*TEENSYDISPLAY_SCALE, overlayMessage);
|
drawString(M_SELECTDISABLED, 1, TEENSYDISPLAY_HEIGHT - (16 + 12)*TEENSYDISPLAY_SCALE, overlayMessage);
|
||||||
}
|
}
|
||||||
nextMessageTime = millis() + 1000;
|
nextMessageTime = millis() + 10; // DEBUGGING FIXME make 1000 again
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -262,17 +265,25 @@ void TeensyDisplay::cachePixel(uint16_t x, uint16_t y, uint8_t color)
|
||||||
// This is the case where we need to blend together neighboring
|
// This is the case where we need to blend together neighboring
|
||||||
// pixels, because we don't have enough physical screen resoultion.
|
// pixels, because we don't have enough physical screen resoultion.
|
||||||
if (x&1) {
|
if (x&1) {
|
||||||
uint8_t origColor = dmaBuffer[y+SCREENINSET_Y][(x>>1)*TEENSYDISPLAY_SCALE+SCREENINSET_X];
|
uint16_t origColor = dmaBuffer[y+SCREENINSET_Y][(x>>1)*TEENSYDISPLAY_SCALE+SCREENINSET_X];
|
||||||
cacheDoubleWidePixel(x>>1, y, color);
|
uint16_t newColor = (uint16_t) loresPixelColors[color];
|
||||||
#if 0
|
|
||||||
uint8_t newColor = (uint16_t) (origColor + color) / 2;
|
|
||||||
if (g_displayType == m_blackAndWhite) {
|
if (g_displayType == m_blackAndWhite) {
|
||||||
cacheDoubleWidePixel(x>>1, y, (origColor && newColor) ? 0xFFFF : 0x0000);
|
// 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 {
|
} else {
|
||||||
cacheDoubleWidePixel(x>>1,y,blendColors(origColor, newColor));
|
cacheDoubleWidePixel(x>>1,y,color);
|
||||||
// Else if it's black, we leave whatever was in the other pixel.
|
// Else if it's black, we leave whatever was in the other pixel.
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
// The even pixels always draw.
|
// The even pixels always draw.
|
||||||
cacheDoubleWidePixel(x>>1,y,color);
|
cacheDoubleWidePixel(x>>1,y,color);
|
||||||
|
@ -289,6 +300,14 @@ void TeensyDisplay::cachePixel(uint16_t x, uint16_t y, uint8_t color)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// "DoubleWide" means "please double the X because I'm in low-res
|
// "DoubleWide" means "please double the X because I'm in low-res
|
||||||
// width mode".
|
// width mode".
|
||||||
|
|
|
@ -31,6 +31,7 @@ class TeensyDisplay : public PhysicalDisplay {
|
||||||
|
|
||||||
virtual void drawImageOfSizeAt(const uint8_t *img, uint16_t sizex, uint8_t sizey, uint16_t wherex, uint8_t wherey);
|
virtual void drawImageOfSizeAt(const uint8_t *img, uint16_t sizex, uint8_t sizey, uint16_t wherex, uint8_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 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 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);
|
virtual void cachePixel(uint16_t x, uint16_t y, uint8_t color);
|
||||||
|
|
|
@ -18,7 +18,8 @@ bool TeensyPrefs::readPrefs(prefs_t *readTo)
|
||||||
*pp++ = EEPROM.read(i);
|
*pp++ = EEPROM.read(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (readTo->magic != PREFSMAGIC) {
|
if (readTo->magic != PREFSMAGIC ||
|
||||||
|
readTo->magicFooter != PREFSMAGIC) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (readTo->prefsSize != sizeof(prefs_t)) {
|
if (readTo->prefsSize != sizeof(prefs_t)) {
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#include "teensy-println.h"
|
#include "teensy-println.h"
|
||||||
#include "smalloc.h"
|
#include "smalloc.h"
|
||||||
|
|
||||||
|
#include "iocompat.h"
|
||||||
|
|
||||||
//#define DEBUG_TIMING
|
//#define DEBUG_TIMING
|
||||||
|
|
||||||
#if F_CPU < 240000000
|
#if F_CPU < 240000000
|
||||||
|
@ -127,7 +129,12 @@ static uint8_t usb_scanmap[256] = {
|
||||||
|
|
||||||
void onKeypress(uint8_t keycode)
|
void onKeypress(uint8_t keycode)
|
||||||
{
|
{
|
||||||
((AppleVM *)g_vm)->getKeyboard()->keyDepressed(usb_scanmap[keycode]);
|
if (keycode == 67) {
|
||||||
|
// F10 is our interrupt button; FIXME this probably needs to be adjustable
|
||||||
|
g_biosInterrupt = true;
|
||||||
|
} else {
|
||||||
|
((AppleVM *)g_vm)->getKeyboard()->keyDepressed(usb_scanmap[keycode]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onKeyrelease(uint8_t keycode)
|
void onKeyrelease(uint8_t keycode)
|
||||||
|
@ -510,7 +517,7 @@ void loop()
|
||||||
wasBios = false;
|
wasBios = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_biosInterrupt) {
|
if (!g_biosInterrupt) {
|
||||||
runCPU(now);
|
runCPU(now);
|
||||||
}
|
}
|
||||||
|
@ -588,11 +595,22 @@ void readPrefs()
|
||||||
if (p.hd2[0]) {
|
if (p.hd2[0]) {
|
||||||
((AppleVM *)g_vm)->insertHD(1, p.hd2);
|
((AppleVM *)g_vm)->insertHD(1, p.hd2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_luminanceCutoff = p.luminanceCutoff;
|
||||||
|
|
||||||
|
g_invertPaddleX = p.invertPaddleX;
|
||||||
|
g_invertPaddleY = p.invertPaddleY;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Set some defaults!
|
||||||
|
g_volume = 7;
|
||||||
|
g_displayType = 3; // FIXME constant
|
||||||
|
g_debugMode = D_NONE;
|
||||||
|
g_speed = 1023000;
|
||||||
|
g_luminanceCutoff = 127;
|
||||||
|
g_invertPaddleX = g_invertPaddleY = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_invertPaddleX = p.invertPaddleX;
|
|
||||||
g_invertPaddleY = p.invertPaddleY;
|
|
||||||
|
|
||||||
// Update the paddles with the new inversion state
|
// Update the paddles with the new inversion state
|
||||||
((TeensyPaddles *)g_paddles)->setRev(g_invertPaddleX, g_invertPaddleY);
|
((TeensyPaddles *)g_paddles)->setRev(g_invertPaddleX, g_invertPaddleY);
|
||||||
}
|
}
|
||||||
|
@ -603,6 +621,7 @@ void writePrefs()
|
||||||
prefs_t p;
|
prefs_t p;
|
||||||
|
|
||||||
p.magic = PREFSMAGIC;
|
p.magic = PREFSMAGIC;
|
||||||
|
p.magicFooter = PREFSMAGIC;
|
||||||
p.prefsSize = sizeof(prefs_t);
|
p.prefsSize = sizeof(prefs_t);
|
||||||
p.version = PREFSVERSION;
|
p.version = PREFSVERSION;
|
||||||
|
|
||||||
|
@ -611,6 +630,7 @@ void writePrefs()
|
||||||
|
|
||||||
p.volume = g_volume;
|
p.volume = g_volume;
|
||||||
p.displayType = g_displayType;
|
p.displayType = g_displayType;
|
||||||
|
p.luminanceCutoff = g_luminanceCutoff;
|
||||||
p.debug = g_debugMode;
|
p.debug = g_debugMode;
|
||||||
p.speed = g_speed / (1023000/2);
|
p.speed = g_speed / (1023000/2);
|
||||||
strcpy(p.disk1, ((AppleVM *)g_vm)->DiskName(0));
|
strcpy(p.disk1, ((AppleVM *)g_vm)->DiskName(0));
|
||||||
|
|
Loading…
Reference in New Issue