Updated source code from Eric Rechlin's Emu48 version 1.62+ that was merged from Christoph Gießelink's Emu48 version 1.63.

This commit is contained in:
dgis 2020-10-30 00:33:10 +01:00
parent 9b995adc51
commit 378a3cf67d
18 changed files with 2977 additions and 2922 deletions

View file

@ -65,6 +65,7 @@ CHANGES
Version 2.0 (2020-11-XX)
- Updated source code from Eric Rechlin's Emu48 version 1.62+ that was merged from Christoph Gießelink's Emu48 version 1.63.
- For the HP49/50 port 2, it is now possible to load a new Flash ROM file (It fully replaces the ROM).
- Replaces the haptic feedback switch with a slider to adjust the vibration duration.
- Fix transparency issue (RGB -> BGR).

View file

@ -53,7 +53,7 @@ add_library( # Sets the name of the library.
src/main/cpp/core/disrpl.c
# src/main/cpp/core/Emu48.c #-> To rewrite
src/main/cpp/core/engine.c
src/main/cpp/core/external.c
# src/main/cpp/core/external.c # Removed in Emu48+ for Windows version 1.62+
src/main/cpp/core/fetch.c
src/main/cpp/core/files.c
src/main/cpp/core/i28f160.c

View file

@ -65,6 +65,7 @@ CHANGES
Version 2.0 (2020-11-XX)
- Updated source code from Eric Rechlin's Emu48 version 1.62+ that was merged from Christoph Gießelink's Emu48 version 1.63.
- For the HP49/50 port 2, it is now possible to load a new Flash ROM file (It fully replaces the ROM).
- Replaces the haptic feedback switch with a slider to adjust the vibration duration.
- Fix transparency issue (RGB -> BGR).

View file

@ -279,7 +279,7 @@ static LRESULT OnPaint(HWND hWindow)
GdiFlush();
}
LeaveCriticalSection(&csGDILock);
UpdateAnnunciators();
UpdateAnnunciators(0x3F);
RefreshButtons(&rcMainPaint);
}
EndPaint(hWindow, &Paint);

View file

@ -13,7 +13,7 @@
#include "kml.h"
#include "debugger.h"
#define VERSION "1.61+"
#define VERSION "1.62+"
#ifdef _DEBUG
LPCTSTR szNoTitle = _T("Emu48 ")_T(VERSION)_T(" Debug");
@ -904,7 +904,7 @@ static LRESULT OnPaint(HWND hWindow)
GdiFlush();
}
LeaveCriticalSection(&csGDILock);
UpdateAnnunciators();
UpdateAnnunciators(0x3F);
RefreshButtons(&rcMainPaint);
}
EndPaint(hWindow, &Paint);

View file

@ -52,7 +52,6 @@
#define DISP_POINTER 0x01 // defines for display area
#define DISP_MAIN 0x02
#define DISP_MENUE 0x04
#define DISP_ANNUN 0x08
#define ROMPAGESIZE (1<<12) // ROM dirty page size in nibbles
@ -182,7 +181,7 @@ extern VOID UpdateMenuDisplay(VOID);
extern VOID RefreshDisp0(); // CdB for HP: add apples display management
extern VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s);
extern VOID WriteToMenuDisplay(LPBYTE a, DWORD d, UINT s);
extern VOID UpdateAnnunciators(VOID);
extern VOID UpdateAnnunciators(DWORD dwUpdateMask);
extern VOID ResizeWindow(VOID);
// Engine.c
@ -374,10 +373,6 @@ extern DWORD RPL_Pick(UINT l);
extern VOID RPL_Replace(DWORD n);
extern VOID RPL_Push(UINT l,DWORD n);
// External.c
extern VOID External(CHIPSET* w);
extern VOID RCKBp(CHIPSET* w);
// SndEnum.c
extern VOID SetSoundDeviceList(HWND hWnd,UINT uDeviceID);

View file

@ -4,7 +4,7 @@
* This file is part of Emu48
*
* Copyright (C) 2005 CdB for HP
* Copyright (C) 2006 Christoph Gie<EFBFBD>elink
* Copyright (C) 2006 Christoph Gießelink
*
*/
#include "pch.h"
@ -20,7 +20,7 @@
#pragma intrinsic(memset,memcpy)
#include "ops.h"
#include "Ops.h"
//
// ROM buffer access functions
@ -158,6 +158,35 @@ VOID o80B40(VOID)
return;
}
// BEEP2
VOID o80B50(CHIPSET* w)
{
BYTE fbeep;
DWORD freq,dur;
freq = Npack(w->D,5); // frequency in Hz
dur = Npack(w->C,5); // duration in ms
Nread(&fbeep,0x80F0F,1); // fetch system flags -53 to -56
w->carry = TRUE; // setting of no beep
if (!(fbeep & 0x8) && freq) // bit -56 clear and frequency > 0 Hz
{
if (freq > 4400) freq = 4400; // high limit of HP (SX)
SoundBeep(freq,dur); // beeping
// estimate cpu cycles for beeping time (4MHz)
w->cycles += dur * 4000;
// original routine return with...
w->P = 0; // P=0
w->intk = TRUE; // INTON
w->carry = FALSE; // RTNCC
}
w->pc = rstkpop();
return;
}
// MOVEDOWN
VOID o80B60(VOID)
{
@ -230,6 +259,38 @@ VOID o80B80(VOID)
return;
}
// RCKBp
VOID o80B90(CHIPSET* w) // ROM Check Beep patch
{
DWORD dw2F,dwCpuFreq;
DWORD freq,dur;
BYTE f,d;
f = w->C[1]; // f = freq ctl
d = w->C[0]; // d = duration ctl
// CPU strobe frequency @ RATE 27 = 3.67MHz
// CPU strobe frequency @ RATE 29 = 3.93MHz
dwCpuFreq = ((27 + 1) * 524288) >> 2;
dw2F = f * 180 + 367; // F=f*90+183.5
freq = dwCpuFreq / dw2F;
dur = (dw2F * (256 - 16 * d)) * 1000 / 2 / dwCpuFreq;
if (freq > 4400) freq = 4400; // high limit of HP
SoundBeep(freq,dur); // beeping
// estimate cpu cycles for beeping time (4MHz)
w->cycles += dur * 4000;
w->P = 0; // P=0
w->carry = FALSE; // RTNCC
w->pc = rstkpop();
return;
}
// setup basic memory configuration
VOID o80B04(VOID)
{
@ -327,11 +388,11 @@ VOID o80BExt(LPBYTE I) // Saturnator extentions
case 0x00: o80B00(); break; // RPL2 (preserve Carry)
case 0x03: o80B30(); break; // FALSE
case 0x04: o80B40(); break; // DOFALSE
case 0x05: External(&w); PCHANGED; break; // BEEP2 implemented using Emu48's beep
case 0x05: o80B50(&w); PCHANGED; break; // BEEP2 implemented using Emu48's beep
case 0x06: o80B60(); break; // MOVEDOWN
case 0x07: o80B70(); break; // MOVEUP
case 0x08: o80B80(); break; // CREATETEMP
case 0x09: RCKBp(&w); PCHANGED; break; // RCKBp
case 0x09: o80B90(&w); PCHANGED; break; // RCKBp (ROM Check Beep patch)
case 0x0A: break; // KEYDN not implemented
case 0x0B: break; // no doslow implemented
case 0x10: // simulate off function

View file

@ -10,9 +10,11 @@
extern VOID o80B00(VOID);
extern VOID o80B30(VOID);
extern VOID o80B40(VOID);
extern VOID o80B50(CHIPSET* w);
extern VOID o80B60(VOID);
extern VOID o80B70(VOID);
extern VOID o80B80(VOID);
extern VOID o80B90(CHIPSET* w);
extern VOID o80B04(VOID);
extern VOID o80B14(VOID);
extern VOID o80B24(VOID);

View file

@ -589,21 +589,26 @@ VOID WriteToMenuDisplay(LPBYTE a, DWORD d, UINT s)
return;
}
VOID UpdateAnnunciators(VOID)
VOID UpdateAnnunciators(DWORD dwUpdateMask)
{
BYTE c;
UINT i;
c = (BYTE)(Chipset.IORam[ANNCTRL] | (Chipset.IORam[ANNCTRL+1]<<4));
// switch annunciators off if timer stopped
if ((c & AON) == 0 || (Chipset.IORam[TIMER2_CTRL] & RUN) == 0)
c = 0;
DrawAnnunciator(1,c&LA1);
DrawAnnunciator(2,c&LA2);
DrawAnnunciator(3,c&LA3);
DrawAnnunciator(4,c&LA4);
DrawAnnunciator(5,c&LA5);
DrawAnnunciator(6,c&LA6);
for (i = 1; i <= 6; ++i)
{
if ((dwUpdateMask & 0x1) != 0) // annunciator changed?
{
DrawAnnunciator(i,c & 0x1);
}
dwUpdateMask >>= 1;
c >>= 1;
}
_ASSERT(dwUpdateMask == 0);
return;
}

View file

@ -73,7 +73,7 @@ static DWORD dwOldCyc; // cpu cycles at last event
static DWORD dwSpeedRef; // timer value at last event
static DWORD dwTickRef; // sample timer ticks
#include "ops.h"
#include "Ops.h"
// save last instruction in circular instruction buffer
static __inline VOID SaveInstrAddr(DWORD dwAddr)
@ -285,7 +285,6 @@ static __inline VOID CheckDisp(BOOL bSync)
_ASSERT((disp & DISP_POINTER) == 0); // display pointer already updated
if (disp & DISP_MAIN) UpdateMainDisplay();
if (disp & DISP_MENUE) UpdateMenuDisplay();
_ASSERT((disp & DISP_ANNUN) == 0); // annunciators already updated
disp = 0; // display updated
return;
}
@ -599,7 +598,7 @@ loop:
UpdateMainDisplay();
UpdateMenuDisplay();
RefreshDisp0(); // CdB for HP: add apples display management
UpdateAnnunciators();
UpdateAnnunciators(0x3F);
// init speed reference
dwOldCyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF);
QueryPerformanceCounter(&lDummyInt);

View file

@ -1,100 +0,0 @@
/*
* external.c
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
* Copyright (C) 2005 Christoph Gießelink
*
*/
#include "pch.h"
#include "Emu48.h"
#include "ops.h"
//| 38G | 39G | 40G | 48SX | 48GX | 49G | Name
//#F0E4F #80F0F #80F0F #706D2 #80850 #80F0F =SFLAG53_56
// memory address for flags -53 to -56
// CdB for HP: add apples beep management
#define SFLAG53_56 ( (cCurrentRomType=='6') \
? 0xE0E4F \
: ( (cCurrentRomType=='A') \
? 0xF0E4F \
: ( (cCurrentRomType!='E' && cCurrentRomType!='X' && cCurrentRomType!='P' && cCurrentRomType!='2' && cCurrentRomType!='Q') \
? ( (cCurrentRomType=='S') \
? 0x706D2 \
: 0x80850 \
) \
: 0x80F0F \
) \
) \
)
VOID External(CHIPSET* w) // Beep patch
{
BYTE fbeep;
DWORD freq,dur;
freq = Npack(w->D,5); // frequency in Hz
dur = Npack(w->C,5); // duration in ms
Nread(&fbeep,SFLAG53_56,1); // fetch system flags -53 to -56
w->carry = TRUE; // setting of no beep
if (!(fbeep & 0x8) && freq) // bit -56 clear and frequency > 0 Hz
{
if (freq > 4400) freq = 4400; // high limit of HP (SX)
SoundBeep(freq,dur); // beeping
// estimate cpu cycles for beeping time (2MHz / 4MHz)
w->cycles += dur * ((cCurrentRomType=='S') ? 2000 : 4000);
// original routine return with...
w->P = 0; // P=0
w->intk = TRUE; // INTON
w->carry = FALSE; // RTNCC
}
w->pc = rstkpop();
return;
}
VOID RCKBp(CHIPSET* w) // ROM Check Beep patch
{
DWORD dw2F,dwCpuFreq;
DWORD freq,dur;
BYTE f,d;
f = w->C[1]; // f = freq ctl
d = w->C[0]; // d = duration ctl
if (cCurrentRomType == 'S') // Clarke chip with 48S ROM
{
// CPU strobe frequency @ RATE 14 = 1.97MHz
dwCpuFreq = ((14 + 1) * 524288) >> 2;
dw2F = f * 126 + 262; // F=f*63+131
}
else // York chip with 48G and later ROM
{
// CPU strobe frequency @ RATE 27 = 3.67MHz
// CPU strobe frequency @ RATE 29 = 3.93MHz
dwCpuFreq = ((27 + 1) * 524288) >> 2;
dw2F = f * 180 + 367; // F=f*90+183.5
}
freq = dwCpuFreq / dw2F;
dur = (dw2F * (256 - 16 * d)) * 1000 / 2 / dwCpuFreq;
if (freq > 4400) freq = 4400; // high limit of HP
SoundBeep(freq,dur); // beeping
// estimate cpu cycles for beeping time (2MHz / 4MHz)
w->cycles += dur * ((cCurrentRomType=='S') ? 2000 : 4000);
w->P = 0; // P=0
w->carry = FALSE; // RTNCC
w->pc = rstkpop();
return;
}

View file

@ -321,7 +321,7 @@ static JMPTAB o8A_[] =
static JMPTAB o81B_[] =
{
(LPCVOID) o_invalid4, F,
(LPCVOID) o81B1, F, // normally o_invalid4, beep patch, Apple: LOOP
(LPCVOID) o81B1, F, // normally o_invalid4, Apple: LOOP
(LPCVOID) o81B2, F,
(LPCVOID) o81B3, F,
(LPCVOID) o81B4, F,

View file

@ -1017,8 +1017,16 @@ BOOL OpenDocument(LPCTSTR szFilename)
case 0xFE: // Win48 2.1 / Emu4x 0.99.x format
// read length of KML script name
ReadFile(hFile,&nLength,sizeof(nLength),&lBytesRead,NULL);
// KML script name too long for file buffer
if (nLength >= ARRAYSIZEOF(szCurrentKml)) goto read_err;
if (nLength >= ARRAYSIZEOF(szCurrentKml))
{
// skip heading KML script name characters until remainder fits into file buffer
UINT nSkip = nLength - (ARRAYSIZEOF(szCurrentKml) - 1);
SetFilePointer(hFile, nSkip, NULL, FILE_CURRENT);
nLength = ARRAYSIZEOF(szCurrentKml) - 1;
}
#if defined _UNICODE
{
LPSTR szTmp = (LPSTR) malloc(nLength);
@ -2575,7 +2583,7 @@ static BOOL LabColorCmp(DWORD dwColor1,DWORD dwColor2,DWORD dwTol)
nDiffCol = (INT) (dwColor1 & 0xFF) - (INT) (dwColor2 & 0xFF);
dwDiff += (DWORD) (nDiffCol * nDiffCol);
dwTol *= dwTol;
return dwDiff > dwTol; // FALSE = colors match
}

View file

@ -2630,9 +2630,8 @@ BOOL InitKML(LPCTSTR szFilename, BOOL bNoLog)
}
if (CheckForBeepPatch()) // check if ROM contain beep patches
{
AddToLog(_T("Warning, ROM beep patch detected. Remove beep patches please."));
bNoLog = FALSE;
bAlwaysDisplayLog = TRUE;
AddToLog(_T("Error, ROM beep patch detected. Remove beep patches please."));
goto quit;
}
ResizeMainBitmap(nScaleMul,nScaleDiv); // resize main picture

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -9,7 +9,7 @@
#include "pch.h"
#include "Emu48.h"
#include "ops.h"
#include "Opcodes.h"
#include "opcodes.h"
#include "io.h"
#include "i28f160.h" // flash support
@ -1307,6 +1307,7 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
BOOL bDISPADDR = FALSE; // flag addr 0x120-0x124 changed
BOOL bLINEOFFS = FALSE; // flag addr 0x125-0x127 changed
BOOL bMENUADDR = FALSE; // flag addr 0x130-0x134 changed
DWORD dwAnnunciator = 0; // no annunciator write
#if defined DEBUG_IO
{
@ -1412,7 +1413,8 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
if (c & RST)
{
CpuReset(); // emulate NRES signal
disp |= (DISP_POINTER | DISP_MAIN | DISP_MENUE | DISP_ANNUN);
disp |= (DISP_POINTER | DISP_MAIN | DISP_MENUE);
dwAnnunciator = 0x3F; // update all annunciators
bInterrupt = TRUE; // SHUTDN
}
break;
@ -1425,11 +1427,9 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
// 0010B @ Annunciator control [LA4 LA3 LA2 LA1] = [ alarm alpha -> <- ]
case 0x0B:
case 0x0C:
if (c!=Chipset.IORam[d])
{
Chipset.IORam[d] = c;
disp |= DISP_ANNUN;
}
// annunciator changed
dwAnnunciator |= ((Chipset.IORam[d] ^c) << ((d - 0x0B) * 4)) & 0x3F;
Chipset.IORam[d] = c;
break;
// 0010D = NS:BAUD
@ -1759,7 +1759,7 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
StartTimers();
else
StopTimers();
disp |= DISP_ANNUN; // update annunciators
dwAnnunciator = 0x3F; // update all annunciators
break;
// 00130 = NS:MENUADDR
@ -1842,10 +1842,9 @@ finish:
disp &= ~DISP_POINTER; // display pointer updated
UpdateDisplayPointers();
}
if (disp & DISP_ANNUN)
if (dwAnnunciator)
{
disp &= ~DISP_ANNUN; // annunciators updated
UpdateAnnunciators();
UpdateAnnunciators(dwAnnunciator);
}
return;
}

View file

@ -4,7 +4,7 @@
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
* Copyright (C) 1999 Christoph Gie<EFBFBD>elink
* Copyright (C) 1999 Christoph Gießelink
*
*/
#include "pch.h"
@ -25,7 +25,7 @@
#pragma intrinsic(memset,memcpy)
#include "ops.h"
#include "Ops.h"
// Fields start and length
UINT F_s[16] = {0/*P*/,0,2,0,15,3,0,0,0,0,0,0,0,0,0,0};
@ -2444,7 +2444,7 @@ VOID o_goyes5(LPBYTE I)
}
//////// EXTENSIONS ////////
VOID o81B1(LPBYTE I) // beep patch
VOID o81B1(LPBYTE I)
{
if (cCurrentRomType=='Q' || cCurrentRomType=='2' || cCurrentRomType=='P')
{
@ -2454,9 +2454,8 @@ VOID o81B1(LPBYTE I) // beep patch
}
else
{
// Emu48 borrows this opcode for the beep patch on the non-ARM-based calculators
External(&w); // beep patch
PCHANGED; // update field select table
// this opcode was used for the beep patch on the non-ARM-based calculators, not used any more
o_invalid4(I);
}
return;
}