2019-03-11: Updated to version 60

Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
This commit is contained in:
Gwenhael Le Moine 2024-03-20 07:46:28 +01:00
parent 311f1aa6b5
commit 9ed4c0cec5
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
15 changed files with 1031 additions and 206 deletions

BIN
Emu48.dll

Binary file not shown.

BIN
Emu48.exe

Binary file not shown.

View file

@ -1,9 +1,3 @@
Additional known bugs and restrictions of Emu48 V1.59+
------------------------------------------------------
- some display issues, such as when scrolling up, that were fixed in
regular Emu48 haven't yet been merged into Emu48+
Known bugs and restrictions of Emu48 V1.61
------------------------------------------

View file

@ -467,8 +467,9 @@ VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s)
if (MAINSCREENHEIGHT == 0) return; // menu disabled
d -= Chipset.start1; // nibble offset to DISPADDR (start of display)
y0 = y = (d / lWidth) + Chipset.d0size; // bitmap row
x0 = x = d % lWidth; // bitmap coloumn
d += SCREENHEIGHTREAL * lWidth; // make positive offset
y0 = y = abs((INT)d / lWidth - SCREENHEIGHTREAL); // bitmap row
x0 = x = (INT)d % lWidth; // bitmap column
p = (DWORD*)(pbyLcd + y0*LCD_ROW + x0*sizeof(*p));
// outside main display area
@ -485,21 +486,46 @@ VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s)
++x; // next x position
if (((INT) x==lWidth)&&s) // end of display line
{
// end of main display area
if (y == (INT)MAINSCREENHEIGHT + Chipset.d0size - 1) break;
x = 0; // first coloumn
++y; // next row
if (y == (INT) MAINSCREENHEIGHT+Chipset.d0size) break;
// recalculate bitmap memory position of new line
p = (DWORD*) (pbyLcd+y*LCD_ROW); // CdB for HP: add 64/80 line display for apples
}
else
p++;
}
if (y==y0) y++;
// update window region
if (y0 != y) // changed more than one line
{
x0 = 0; // no x-position offset
x = 131; // redraw complete lines
++y; // redraw this line as well
}
else
{
x0 <<= 2; x <<= 2; // x-position in pixel
_ASSERT(x >= x0); // can't draw negative number of pixel
x -= x0; // number of pixels to update
x0 -= Chipset.boffset; // adjust x-position with left margin
if (x0 < 0) x0 = 0;
if (x0 > 131) x0 = 131; // cut right borders
if (x + x0 > 131) x = 131 - x0;
y = y0 + 1; // draw one line
}
EnterCriticalSection(&csGDILock); // solving NT GDI problems
{
StretchBlt(hWindowDC, nLcdX, nLcdY+y0*nLcdZoom*nGdiYZoom,
131*nLcdZoom*nGdiXZoom, (y-y0)*nLcdZoom*nGdiYZoom,
hLcdDC, Chipset.boffset, y0, 131, y-y0, SRCCOPY); // CdB for HP: add 64/80 line display for apples
StretchBlt(hWindowDC, nLcdX + x0*nLcdZoom*nGdiXZoom, nLcdY+y0*nLcdZoom*nGdiYZoom,
x*nLcdZoom*nGdiXZoom, (y-y0)*nLcdZoom*nGdiYZoom,
hLcdDC, x0 + Chipset.boffset, y0, x, y-y0, SRCCOPY); // CdB for HP: add 64/80 line display for apples
GdiFlush();
}
LeaveCriticalSection(&csGDILock);

View file

@ -13,7 +13,7 @@
#include "kml.h"
#include "debugger.h"
#define VERSION "1.59+"
#define VERSION "1.60+"
#ifdef _DEBUG
LPCTSTR szNoTitle = _T("Emu48 ")_T(VERSION)_T(" Debug");

View file

@ -28,9 +28,6 @@
#define CF_HPOBJ "CF_HPOBJ" // clipboard format for DDE
// CPU cycles in 16384 Hz time frame
#define T2CYCLES ((cCurrentRomType=='S')?dwSXCycles:(cCurrentRomType=='G')?dwGXCycles:(cCurrentRomType=='P')?dwGPCycles:(cCurrentRomType=='Q')?dwGPCycles:dwG2Cycles) // CdB for HP: add apples
#define SM_RUN 0 // states of cpu emulation thread
#define SM_INVALID 1
#define SM_RETURN 2
@ -205,6 +202,7 @@ extern DWORD dwSXCycles;
extern DWORD dwGXCycles;
extern DWORD dwGPCycles; // CdB for HP: add apples speed
extern DWORD dwG2Cycles; // CdB for HP: add apples speed
extern DWORD dwT2Cycles;
extern HANDLE hEventDebug;
extern BOOL bDbgAutoStateCtrl;
extern INT nDbgState;
@ -266,6 +264,7 @@ extern BOOL bBackup;
extern VOID SetWindowLocation(HWND hWnd,INT nPosX,INT nPosY);
extern DWORD GetCutPathName(LPCTSTR szFileName,LPTSTR szBuffer,DWORD dwBufferLength,INT nCutLength);
extern VOID SetWindowPathTitle(LPCTSTR szFileName);
extern BOOL CheckForBeepPatch(VOID);
extern VOID UpdatePatches(BOOL bPatch);
extern BOOL PatchRom(LPCTSTR szFilename);
extern BOOL CrcRom(WORD *pwChk);

View file

@ -295,7 +295,7 @@ FONT 8, "MS Sans Serif"
BEGIN
ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE
LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP
LTEXT "Copyright © 2018 Christoph Gießelink && Sébastien Carlier",
LTEXT "Copyright © 2019 Christoph Gießelink && Sébastien Carlier",
IDC_STATIC,29,18,181,8
DEFPUSHBUTTON "OK",IDOK,215,12,39,14
EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL |
@ -691,8 +691,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,5,9,0
PRODUCTVERSION 1,5,9,0
FILEVERSION 1,6,0,0
PRODUCTVERSION 1,6,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -709,12 +709,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\0"
VALUE "FileDescription", "HP38/39/40/48/49/50 Emulator\0"
VALUE "FileVersion", "1, 5, 9, 0\0"
VALUE "FileVersion", "1, 6, 0, 0\0"
VALUE "InternalName", "Emu48\0"
VALUE "LegalCopyright", "Copyright © 2018\0"
VALUE "LegalCopyright", "Copyright © 2019\0"
VALUE "OriginalFilename", "Emu48.exe\0"
VALUE "ProductName", "Emu48\0"
VALUE "ProductVersion", "1, 5, 9, 0\0"
VALUE "ProductVersion", "1, 6, 0, 0\0"
END
END
BLOCK "VarFileInfo"

View file

@ -34,6 +34,8 @@ DWORD dwGXCycles = 123; // GX cpu cycles in interval
DWORD dwGPCycles = 123*3; // g+ cpu cycles in interval // CdB for HP: add apples display management
DWORD dwG2Cycles = 123*2; // gII cpu cycles in interval // CdB for HP: add apples display management
DWORD dwT2Cycles = 0xFFFFFFFF; // CPU cycles in 16384 Hz time frame
// variables for debugger engine
HANDLE hEventDebug; // event handle to stop cpu thread
@ -201,11 +203,11 @@ static __inline VOID Debugger(VOID) // debugger part
{
// cpu cycles for one timer2 tick elapsed
if ((DWORD) (Chipset.cycles & 0xFFFFFFFF) - dwEDbgCycles
>= (SAMPLE / 8192) * (DWORD) T2CYCLES)
>= (SAMPLE / 8192) * dwT2Cycles)
{
--Chipset.t2;
// adjust cycles reference
dwEDbgCycles += (SAMPLE / 8192) * T2CYCLES;
dwEDbgCycles += (SAMPLE / 8192) * dwT2Cycles;
}
}
else // new timer2 value
@ -293,7 +295,7 @@ static __inline VOID AdjustSpeed(VOID) // adjust emulation speed
EnterCriticalSection(&csSlowLock);
{
// cycles elapsed for next check
if ((dwCycles = (DWORD) (Chipset.cycles & 0xFFFFFFFF)-dwOldCyc) >= (DWORD) T2CYCLES)
if ((dwCycles = (DWORD) (Chipset.cycles & 0xFFFFFFFF)-dwOldCyc) >= dwT2Cycles)
{
LARGE_INTEGER lAct;
do
@ -306,7 +308,7 @@ static __inline VOID AdjustSpeed(VOID) // adjust emulation speed
// ticks elapsed or negative number (workaround for QueryPerformanceCounter() in Win2k)
while (dwTicks <= dwTickRef || (dwTicks & 0x80000000) != 0);
dwOldCyc += T2CYCLES; // adjust cycles reference
dwOldCyc += dwT2Cycles; // adjust cycles reference
dwSpeedRef += dwTickRef; // adjust reference time
}
@ -317,6 +319,32 @@ static __inline VOID AdjustSpeed(VOID) // adjust emulation speed
return;
}
static __inline VOID SetT2Cycles(VOID) // set device specific cpu cycles in interval
{
switch (cCurrentRomType)
{
case 'S': // HP48SX
dwT2Cycles = dwSXCycles;
break;
case '6': // HP38G with 64KB RAM
case 'A': // HP38G
case 'E': // HP39/40G
case 'G': // HP48GX
case 'X': // HP49G
default:
dwT2Cycles = dwGXCycles;
break;
case 'P': // HP39G+
case 'Q': // HP49G+
dwT2Cycles = dwGPCycles;
break;
case '2': // HP48GII
dwT2Cycles = dwG2Cycles;
break;
}
return;
}
VOID CheckSerial(VOID)
{
// COM port closed and serial on
@ -387,7 +415,7 @@ VOID UpdateKdnBit(VOID) // update KDN bit
{
if ( Chipset.intk
&& (Chipset.IORam[TIMER2_CTRL]&RUN) != 0
&& (DWORD) (Chipset.cycles & 0xFFFFFFFF) - Chipset.dwKdnCycles > (DWORD) T2CYCLES * 16)
&& (DWORD) (Chipset.cycles & 0xFFFFFFFF) - Chipset.dwKdnCycles > dwT2Cycles * 16)
IOBit(SRQ2,KDN,Chipset.in != 0);
return;
}
@ -570,6 +598,7 @@ loop:
dwOldCyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF);
QueryPerformanceCounter(&lDummyInt);
dwSpeedRef = lDummyInt.LowPart;
SetT2Cycles(); // set device specific cpu cycles in interval
SetHP48Time(); // update HP48 time & date
// start display counter/update engine
StartDisplay((BYTE)(((Chipset.IORam[LINECOUNT+1]<<4)|Chipset.IORam[LINECOUNT])&0x3F));

View file

@ -194,6 +194,71 @@ VOID SetWindowPathTitle(LPCTSTR szFileName)
//################
//#
//# BEEP Patch check
//#
//################
BOOL CheckForBeepPatch(VOID)
{
typedef struct beeppatch
{
const DWORD dwAddress; // patch address
const BYTE byPattern[4]; // patch pattern
} BEEPPATCH, *PBEEPPATCH;
// known beep patches
const BEEPPATCH s38[] = { { 0x017D0, { 0x8, 0x1, 0xB, 0x1 } } };
const BEEPPATCH s39[] = { { 0x017BC, { 0x8, 0x1, 0xB, 0x1 } } };
const BEEPPATCH s48[] = { { 0x017A6, { 0x8, 0x1, 0xB, 0x1 } } };
const BEEPPATCH s49[] = { { 0x4157A, { 0x8, 0x1, 0xB, 0x1 } }, // 1.18/1.19-5/1.19-6
{ 0x41609, { 0x8, 0x1, 0xB, 0x1 } } }; // 1.24/2.01/2.09
const BEEPPATCH *psData;
UINT nDataItems;
BOOL bMatch;
switch (cCurrentRomType)
{
case '6':
case 'A': // HP38G
psData = s38;
nDataItems = ARRAYSIZEOF(s38);
break;
case 'E': // HP39/40G
psData = s39;
nDataItems = ARRAYSIZEOF(s39);
break;
case 'S': // HP48SX
case 'G': // HP48GX
psData = s48;
nDataItems = ARRAYSIZEOF(s48);
break;
case 'X': // HP49G
psData = s49;
nDataItems = ARRAYSIZEOF(s49);
break;
default:
psData = NULL;
nDataItems = 0;
}
// check if one data set match
for (bMatch = FALSE; !bMatch && nDataItems > 0; --nDataItems)
{
_ASSERT(pbyRom != NULL && psData != NULL);
// pattern matching?
bMatch = (psData->dwAddress + ARRAYSIZEOF(psData->byPattern) < dwRomSize)
&& (memcmp(&pbyRom[psData->dwAddress],psData->byPattern,ARRAYSIZEOF(psData->byPattern))) == 0;
++psData; // next data set
}
return bMatch;
}
//################
//#
//# Patch

View file

@ -2614,9 +2614,14 @@ BOOL InitKML(LPCTSTR szFilename, BOOL bNoLog)
if (!CrcRom(&wRomCrc)) // build patched ROM fingerprint and check for unpacked data
{
AddToLog(_T("Error, packed ROM image detected."));
UnmapRom(); // free memory
goto quit;
}
if (CheckForBeepPatch()) // check if ROM contain beep patches
{
AddToLog(_T("Warning, ROM beep patch detected. Remove beep patches please."));
bNoLog = FALSE;
bAlwaysDisplayLog = TRUE;
}
ResizeMainBitmap(nScaleMul,nScaleDiv); // resize main picture
CreateLcdBitmap();

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
LodePNG version 20180611
LodePNG version 20180910
Copyright (c) 2005-2018 Lode Vandevenne
@ -255,7 +255,7 @@ const char* lodepng_error_text(unsigned code);
typedef struct LodePNGDecompressSettings LodePNGDecompressSettings;
struct LodePNGDecompressSettings
{
/* Check LodePNGDecoderSettings for more ignorable errors */
/* Check LodePNGDecoderSettings for more ignorable errors such as ignore_crc */
unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/
/*use custom zlib decoder instead of built in one (default: null)*/
@ -360,6 +360,8 @@ void lodepng_color_mode_init(LodePNGColorMode* info);
void lodepng_color_mode_cleanup(LodePNGColorMode* info);
/*return value is error code (0 means no error)*/
unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source);
/* Makes a temporary LodePNGColorMode that does not need cleanup (no palette) */
LodePNGColorMode lodepng_color_mode_make(LodePNGColorType colortype, unsigned bitdepth);
void lodepng_palette_clear(LodePNGColorMode* info);
/*add 1 color to the palette*/
@ -415,18 +417,30 @@ typedef struct LodePNGInfo
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
/*
suggested background color chunk (bKGD)
This color uses the same color mode as the PNG (except alpha channel), which can be 1-bit to 16-bit.
Suggested background color chunk (bKGD)
For greyscale PNGs, r, g and b will all 3 be set to the same. When encoding
the encoder writes the red one. For palette PNGs: When decoding, the RGB value
will be stored, not a palette index. But when encoding, specify the index of
the palette in background_r, the other two are then ignored.
This uses the same color mode and bit depth as the PNG (except no alpha channel),
with values truncated to the bit depth in the unsigned integer.
The decoder does not use this background color to edit the color of pixels.
For greyscale and palette PNGs, the value is stored in background_r. The values
in background_g and background_b are then unused.
So when decoding, you may get these in a different color mode than the one you requested
for the raw pixels.
When encoding with auto_convert, you must use the color model defined in info_png.color for
these values. The encoder normally ignores info_png.color when auto_convert is on, but will
use it to interpret these values (and convert copies of them to its chosen color model).
When encoding, avoid setting this to an expensive color, such as a non-grey value
when the image is grey, or the compression will be worse since it will be forced to
write the PNG with a more expensive color mode (when auto_convert is on).
The decoder does not use this background color to edit the color of pixels. This is a
completely optional metadata feature.
*/
unsigned background_defined; /*is a suggested background color given?*/
unsigned background_r; /*red component of suggested background color*/
unsigned background_r; /*red/grey/palette component of suggested background color*/
unsigned background_g; /*green component of suggested background color*/
unsigned background_b; /*blue component of suggested background color*/
@ -437,6 +451,10 @@ typedef struct LodePNGInfo
text_strings, while text_keys are keywords that give a short description what
the actual text represents, e.g. Title, Author, Description, or anything else.
All the string fields below including keys, names and language tags are null terminated.
The PNG specification uses null characters for the keys, names and tags, and forbids null
characters to appear in the main text which is why we can use null termination everywhere here.
A keyword is minimum 1 character and maximum 79 characters long. It's
discouraged to use a single line length longer than 79 characters for texts.
@ -469,11 +487,86 @@ typedef struct LodePNGInfo
unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/
/*
unknown chunks
There are 3 buffers, one for each position in the PNG where unknown chunks can appear
each buffer contains all unknown chunks for that position consecutively
The 3 buffers are the unknown chunks between certain critical chunks:
0: IHDR-PLTE, 1: PLTE-IDAT, 2: IDAT-IEND
Color profile related chunks: gAMA, cHRM, sRGB, iCPP
LodePNG does not apply any color conversions on pixels in the encoder or decoder and does not interpret these color
profile values. It merely passes on the information. If you wish to use color profiles and convert colors, please
use these values with a color management library.
See the PNG, ICC and sRGB specifications for more information about the meaning of these values.
*/
/* gAMA chunk: optional, overridden by sRGB or iCCP if those are present. */
unsigned gama_defined; /* Whether a gAMA chunk is present (0 = not present, 1 = present). */
unsigned gama_gamma; /* Gamma exponent times 100000 */
/* cHRM chunk: optional, overridden by sRGB or iCCP if those are present. */
unsigned chrm_defined; /* Whether a cHRM chunk is present (0 = not present, 1 = present). */
unsigned chrm_white_x; /* White Point x times 100000 */
unsigned chrm_white_y; /* White Point y times 100000 */
unsigned chrm_red_x; /* Red x times 100000 */
unsigned chrm_red_y; /* Red y times 100000 */
unsigned chrm_green_x; /* Green x times 100000 */
unsigned chrm_green_y; /* Green y times 100000 */
unsigned chrm_blue_x; /* Blue x times 100000 */
unsigned chrm_blue_y; /* Blue y times 100000 */
/*
sRGB chunk: optional. May not appear at the same time as iCCP.
If gAMA is also present gAMA must contain value 45455.
If cHRM is also present cHRM must contain respectively 31270,32900,64000,33000,30000,60000,15000,6000.
*/
unsigned srgb_defined; /* Whether an sRGB chunk is present (0 = not present, 1 = present). */
unsigned srgb_intent; /* Rendering intent: 0=perceptual, 1=rel. colorimetric, 2=saturation, 3=abs. colorimetric */
/*
iCCP chunk: optional. May not appear at the same time as sRGB.
LodePNG does not parse or use the ICC profile (except its color space header field for an edge case), a
separate library to handle the ICC data (not included in LodePNG) format is needed to use it for color
management and conversions.
For encoding, if iCCP is present, gAMA and cHRM are recommended to be added as well with values that match the ICC
profile as closely as possible, if you wish to do this you should provide the correct values for gAMA and cHRM and
enable their '_defined' flags since LodePNG will not automatically compute them from the ICC profile.
For encoding, the ICC profile is required by the PNG specification to be an "RGB" profile for non-grey
PNG color types and a "GRAY" profile for grey PNG color types. If you disable auto_convert, you must ensure
the ICC profile type matches your requested color type, else the encoder gives an error. If auto_convert is
enabled (the default), and the ICC profile is not a good match for the pixel data, this will result in an encoder
error if the pixel data has non-grey pixels for a GRAY profile, or a silent less-optimal compression of the pixel
data if the pixels could be encoded as greyscale but the ICC profile is RGB.
To avoid this do not set an ICC profile in the image unless there is a good reason for it, and when doing so
make sure you compute it carefully to avoid the above problems.
*/
unsigned iccp_defined; /* Whether an iCCP chunk is present (0 = not present, 1 = present). */
char* iccp_name; /* Null terminated string with profile name, 1-79 bytes */
/*
The ICC profile in iccp_profile_size bytes.
Don't allocate this buffer yourself. Use the init/cleanup functions
correctly and use lodepng_set_icc and lodepng_clear_icc.
*/
unsigned char* iccp_profile;
unsigned iccp_profile_size; /* The size of iccp_profile in bytes */
/* End of color profile related chunks */
/*
unknown chunks: chunks not known by LodePNG, passed on byte for byte.
There are 3 buffers, one for each position in the PNG where unknown chunks can appear.
Each buffer contains all unknown chunks for that position consecutively.
The 3 positions are:
0: between IHDR and PLTE, 1: between PLTE and IDAT, 2: between IDAT and IEND.
For encoding, do not store critical chunks or known chunks that are enabled with a "_defined" flag
above in here, since the encoder will blindly follow this and could then encode an invalid PNG file
(such as one with two IHDR chunks or the disallowed combination of sRGB with iCCP). But do use
this if you wish to store an ancillary chunk that is not supported by LodePNG (such as sPLT or hIST),
or any non-standard PNG chunk.
Do not allocate or traverse this data yourself. Use the chunk traversing functions declared
later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct.
*/
@ -489,12 +582,16 @@ void lodepng_info_cleanup(LodePNGInfo* info);
unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source);
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str); /*push back both texts at once*/
void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/
unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag,
const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/
void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/
/*replaces if exists*/
unsigned lodepng_set_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size);
void lodepng_clear_icc(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
/*
@ -521,10 +618,14 @@ typedef struct LodePNGDecoderSettings
{
LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/
/* Check LodePNGDecompressSettings for more ignorable errors */
/* Check LodePNGDecompressSettings for more ignorable errors such as ignore_adler32 */
unsigned ignore_crc; /*ignore CRC checksums*/
unsigned ignore_critical; /*ignore unknown critical chunks*/
unsigned ignore_end; /*ignore issues at end of file if possible (missing IEND chunk, too large chunk, ...)*/
/* TODO: make a system involving warnings with levels and a strict mode instead. Other potentially recoverable
errors: srgb rendering intent value, size of content of ancillary chunks, more than 79 characters for some
strings, placement/combination rules for ancillary chunks, crc of unknown chunks, allowed characters
in string keys, etc... */
unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/
@ -558,8 +659,11 @@ typedef enum LodePNGFilterStrategy
LFS_PREDEFINED
} LodePNGFilterStrategy;
/*Gives characteristics about the colors of the image, which helps decide which color model to use for encoding.
Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.*/
/*Gives characteristics about the integer RGBA colors of the image (count, alpha channel usage, bit depth, ...),
which helps decide which color model to use for encoding.
Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.
NOTE: This is not related to the ICC color profile, search "iccp_profile" instead to find the ICC/chromacity/...
fields in this header file.*/
typedef struct LodePNGColorProfile
{
unsigned colored; /*not greyscale*/
@ -571,11 +675,14 @@ typedef struct LodePNGColorProfile
unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16.*/
unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order*/
unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for greyscale only. 16 if 16-bit per channel required.*/
size_t numpixels;
} LodePNGColorProfile;
void lodepng_color_profile_init(LodePNGColorProfile* profile);
/*Get a LodePNGColorProfile of the image.*/
/*Get a LodePNGColorProfile of the image. The profile must already have been inited.
NOTE: This is not related to the ICC color profile, search "iccp_profile" instead to find the ICC/chromacity/...
fields in this header file.*/
unsigned lodepng_get_color_profile(LodePNGColorProfile* profile,
const unsigned char* image, unsigned w, unsigned h,
const LodePNGColorMode* mode_in);
@ -657,7 +764,7 @@ unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h,
/*
Read the PNG header, but not the actual data. This returns only the information
that is in the header chunk of the PNG, such as width, height and color type. The
that is in the IHDR chunk of the PNG, such as width, height and color type. The
information is placed in the info_png field of the LodePNGState.
*/
unsigned lodepng_inspect(unsigned* w, unsigned* h,
@ -665,6 +772,20 @@ unsigned lodepng_inspect(unsigned* w, unsigned* h,
const unsigned char* in, size_t insize);
#endif /*LODEPNG_COMPILE_DECODER*/
/*
Reads one metadata chunk (other than IHDR) of the PNG file and outputs what it
read in the state. Returns error code on failure.
Use lodepng_inspect first with a new state, then e.g. lodepng_chunk_find_const
to find the desired chunk type, and if non null use lodepng_inspect_chunk (with
chunk_pointer - start_of_file as pos).
Supports most metadata chunks from the PNG standard (gAMA, bKGD, tEXt, ...).
Ignores unsupported, unknown, non-metadata or IHDR chunks (without error).
Requirements: &in[pos] must point to start of a chunk, must use regular
lodepng_inspect first since format of most other chunks depends on IHDR, and if
there is a PLTE chunk, that one must be inspected before tRNS or bKGD.
*/
unsigned lodepng_inspect_chunk(LodePNGState* state, size_t pos,
const unsigned char* in, size_t insize);
#ifdef LODEPNG_COMPILE_ENCODER
/*This function allocates the out buffer with standard malloc and stores the size in *outsize.*/
@ -678,11 +799,23 @@ The lodepng_chunk functions are normally not needed, except to traverse the
unknown chunks stored in the LodePNGInfo struct, or add new ones to it.
It also allows traversing the chunks of an encoded PNG file yourself.
PNG standard chunk naming conventions:
First byte: uppercase = critical, lowercase = ancillary
Second byte: uppercase = public, lowercase = private
Third byte: must be uppercase
Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy
The chunk pointer always points to the beginning of the chunk itself, that is
the first byte of the 4 length bytes.
In the PNG file format, chunks have the following format:
-4 bytes length: length of the data of the chunk in bytes (chunk itself is 12 bytes longer)
-4 bytes chunk type (ASCII a-z,A-Z only, see below)
-length bytes of data (may be 0 bytes if length was 0)
-4 bytes of CRC, computed on chunk name + data
The first chunk starts at the 8th byte of the PNG file, the entire rest of the file
exists out of concatenated chunks with the above format.
PNG standard chunk ASCII naming conventions:
-First byte: uppercase = critical, lowercase = ancillary
-Second byte: uppercase = public, lowercase = private
-Third byte: must be uppercase
-Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy
*/
/*
@ -717,10 +850,24 @@ unsigned lodepng_chunk_check_crc(const unsigned char* chunk);
/*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/
void lodepng_chunk_generate_crc(unsigned char* chunk);
/*iterate to next chunks. don't use on IEND chunk, as there is no next chunk then*/
/*
Iterate to next chunks, allows iterating through all chunks of the PNG file.
Input must be at the beginning of a chunk (result of a previous lodepng_chunk_next call,
or the 8th byte of a PNG file which always has the first chunk), or alternatively may
point to the first byte of the PNG file (which is not a chunk but the magic header, the
function will then skip over it and return the first real chunk).
Expects at least 8 readable bytes of memory in the input pointer.
Will output pointer to the start of the next chunk or the end of the file if there
is no more chunk after this. Start this process at the 8th byte of the PNG file.
In a non-corrupt PNG file, the last chunk should have name "IEND".
*/
unsigned char* lodepng_chunk_next(unsigned char* chunk);
const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk);
/*Finds the first chunk with the given type in the range [chunk, end), or returns NULL if not found.*/
unsigned char* lodepng_chunk_find(unsigned char* chunk, const unsigned char* end, const char type[5]);
const unsigned char* lodepng_chunk_find_const(const unsigned char* chunk, const unsigned char* end, const char type[5]);
/*
Appends chunk to the data in out. The given chunk should already have its chunk header.
The out variable and outlength are updated to reflect the new reallocated buffer.
@ -894,13 +1041,15 @@ TODO:
[.] test if there are no memory leaks or security exploits - done a lot but needs to be checked often
[.] check compatibility with various compilers - done but needs to be redone for every newer version
[X] converting color to 16-bit per channel types
[ ] read all public PNG chunk types (but never let the color profile and gamma ones touch RGB values)
[X] support color profile chunk types (but never let them touch RGB values by default)
[ ] support all public PNG chunk types
[ ] make sure encoder generates no chunks with size > (2^31)-1
[ ] partial decoding (stream processing)
[X] let the "isFullyOpaque" function check color keys and transparent palettes too
[X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl"
[ ] don't stop decoding on errors like 69, 57, 58 (make warnings)
[ ] make warnings like: oob palette, checksum fail, data after iend, wrong/unknown crit chunk, no null terminator in text, ...
[ ] errors with line numbers (and version)
[ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes
[ ] allow user to provide custom color conversion functions, e.g. for premultiplied alpha, padding bits or not, ...
[ ] allow user to give data (void*) to custom allocator
@ -1614,6 +1763,11 @@ yyyymmdd.
Some changes aren't backwards compatible. Those are indicated with a (!)
symbol.
*) 10 sep 2018: added way to inspect metadata chunks without full decoding.
*) 19 aug 2018 (!): fixed color mode bKGD is encoded with and made it use
palette index in case of palette.
*) 10 aug 2018 (!): added support for gAMA, cHRM, sRGB and iCCP chunks. This
change is backwards compatible unless you relied on unknown_chunks for those.
*) 11 jun 2018: less restrictive check for pixel size integer overflow
*) 14 jan 2018: allow optionally ignoring a few more recoverable errors
*) 17 sep 2017: fix memory leak for some encoder input error cases

View file

@ -1086,7 +1086,7 @@ VOID o80810(LPBYTE I) // RSI
ScanKeyboard(TRUE,TRUE); // one input bit high (direct)?
// enable KDN update
w.dwKdnCycles = (DWORD) (w.cycles & 0xFFFFFFFF) - (DWORD) T2CYCLES * 16;
w.dwKdnCycles = (DWORD) (w.cycles & 0xFFFFFFFF) - dwT2Cycles * 16;
if (w.in && w.inte == FALSE) // key interrupt pending
w.intd = TRUE; // keyboard interrupt pending

View file

@ -448,7 +448,7 @@ VOID SoundOut(CHIPSET* w, WORD wOut)
dwDiffSatCycles = dwCycles - dwLastCyc; // time difference from syncpoint in original Saturn cycles
// theoretical CPU frequency from given T2CYCLES
dwCpuFreq = T2CYCLES * 16384;
dwCpuFreq = dwT2Cycles * 16384;
if (dwDiffSatCycles > dwCpuFreq / 2) // frequency < 1 Hz
{

View file

@ -50,7 +50,7 @@ static DWORD CalcT2(VOID) // calculate timer2 value
DWORD dwT2Dif;
// timer should run a little bit faster (10%) than maschine in authentic speed mode
DWORD dwCycPerTick = (9 * T2CYCLES) / 5;
DWORD dwCycPerTick = (9 * dwT2Cycles) / 5;
QueryPerformanceCounter(&lT2Act); // actual time
// calculate realtime timer2 ticks since reference point