00cc9309cb
de6e324bdseparate emu thread10d3daf86Roms List improvements95d202f37Let's make the rom list process on a separate thread so the emulator doesnt take ages to load.fc306967fWow the ROM Header was just completely busted. Game list view works nowbad1691eefuck this shit2b59e5f46game list in progressd26417b83remappable inputs in progressac4af8106inpute72abc240update readme430139dc9Qt6 frontend3080d4d45Fix this small bug too08cd13b85Cop0 unused functions do not actually pose a threat (as per manual). They don't do anything, so shall we.61bb4fb44make idle loop detection a little more specific with where the load goesb037de4c3SAZDFsdff12e81e73eneed to figure out why n64-systemtest loops indefinitely at some address that appears to be valid (i think it's me not invalidating the cache properly)204f0e13bidle skipping seems to work!cb8bb634asdkfjlasdf58e5c89c1Fix compilation issue on my machine (no idea)24fb2898eattempting more serious idle skipping214719577Place rsp.Step inside cached interpreter. Gains about 3 more fpsbb97dcc23mmmmm920b77d38wjkhasdfjhkasdf430ccdab4it's a start...4f42a673aCached interpreter plays Mario 64. Start looking into RSP as wellc9a030787idle skipping works!5fbda03cenew idea366637abaIdle skipping... maybe?609fa2fb0Cache instructions implemented but broken lmao. Commented out for nowe140a6d12- Stop using inheritance for CPU, instead use composition. - Introduce KAIZEN_JIT_ENABLED optional define instead of relying on __aarch64__ and the like. - More cache work68e613057prep cache impl811b4d809fix clang formatfda755f7didkd5024ebbfsmall MI refactor in preparation of (eventually) implementing the RDRAM interface properly694b45341Merge commit '206dcdedf195fb320913584180edb12c7731e396' as 'external/SDL'206dcdedfSquashed 'external/SDL/' content from commit 4d17b99d0a4d16e1cb4need to update sdl848b19920Fix compilation errordb61b5299Merge commit 'e94a94559f28e49678fbcf72199a5258137b0fe9' as 'external/imgui'e94a94559Squashed 'external/imgui/' content from commit 02e9b8cac52edb3757need to update imguic1a705e86Emulate weird JALR behaviour4b4c32f4bFix exception for "unusable COP1" in 4 instructions i missed accidentally (again)df5828142Bug putting 0s in the log everywheref8b580048Make isviewer a sink to file8241e9735Fix exception for "unusable COP1" in 4 instructions i missed accidentallyb29715f20small changesd9a620bc1make use of my new small utility library0d1aa938eAdd 'external/ircolib/' from commit 'ce3cd726c8df8388d554abf8bb55d55020eb4450'e64eb40b3Fuck git git-subtree-dir: external/ircolib git-subtree-split:de6e324bde
170 lines
5.3 KiB
C
170 lines
5.3 KiB
C
/* Ppmd.h -- PPMD codec common code
|
|
2023-03-05 : Igor Pavlov : Public domain
|
|
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
|
|
|
#ifndef ZIP7_INC_PPMD_H
|
|
#define ZIP7_INC_PPMD_H
|
|
|
|
#include "CpuArch.h"
|
|
|
|
EXTERN_C_BEGIN
|
|
|
|
#if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4)
|
|
/*
|
|
PPMD code always uses 32-bit internal fields in PPMD structures to store internal references in main block.
|
|
if (PPMD_32BIT is defined), the PPMD code stores internal pointers to 32-bit reference fields.
|
|
if (PPMD_32BIT is NOT defined), the PPMD code stores internal UInt32 offsets to reference fields.
|
|
if (pointer size is 64-bit), then (PPMD_32BIT) mode is not allowed,
|
|
if (pointer size is 32-bit), then (PPMD_32BIT) mode is optional,
|
|
and it's allowed to disable PPMD_32BIT mode even if pointer is 32-bit.
|
|
PPMD code works slightly faster in (PPMD_32BIT) mode.
|
|
*/
|
|
#define PPMD_32BIT
|
|
#endif
|
|
|
|
#define PPMD_INT_BITS 7
|
|
#define PPMD_PERIOD_BITS 7
|
|
#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS))
|
|
|
|
#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift))
|
|
#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2)
|
|
#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob))
|
|
#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob))
|
|
|
|
#define PPMD_N1 4
|
|
#define PPMD_N2 4
|
|
#define PPMD_N3 4
|
|
#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
|
|
#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
|
|
|
|
MY_CPU_pragma_pack_push_1
|
|
/* Most compilers works OK here even without #pragma pack(push, 1), but some GCC compilers need it. */
|
|
|
|
/* SEE-contexts for PPM-contexts with masked symbols */
|
|
typedef struct
|
|
{
|
|
UInt16 Summ; /* Freq */
|
|
Byte Shift; /* Speed of Freq change; low Shift is for fast change */
|
|
Byte Count; /* Count to next change of Shift */
|
|
} CPpmd_See;
|
|
|
|
#define Ppmd_See_UPDATE(p) \
|
|
{ if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
|
|
{ (p)->Summ = (UInt16)((p)->Summ << 1); \
|
|
(p)->Count = (Byte)(3 << (p)->Shift++); }}
|
|
|
|
|
|
typedef struct
|
|
{
|
|
Byte Symbol;
|
|
Byte Freq;
|
|
UInt16 Successor_0;
|
|
UInt16 Successor_1;
|
|
} CPpmd_State;
|
|
|
|
typedef struct CPpmd_State2_
|
|
{
|
|
Byte Symbol;
|
|
Byte Freq;
|
|
} CPpmd_State2;
|
|
|
|
typedef struct CPpmd_State4_
|
|
{
|
|
UInt16 Successor_0;
|
|
UInt16 Successor_1;
|
|
} CPpmd_State4;
|
|
|
|
MY_CPU_pragma_pop
|
|
|
|
/*
|
|
PPMD code can write full CPpmd_State structure data to CPpmd*_Context
|
|
at (byte offset = 2) instead of some fields of original CPpmd*_Context structure.
|
|
|
|
If we use pointers to different types, but that point to shared
|
|
memory space, we can have aliasing problem (strict aliasing).
|
|
|
|
XLC compiler in -O2 mode can change the order of memory write instructions
|
|
in relation to read instructions, if we have use pointers to different types.
|
|
|
|
To solve that aliasing problem we use combined CPpmd*_Context structure
|
|
with unions that contain the fields from both structures:
|
|
the original CPpmd*_Context and CPpmd_State.
|
|
So we can access the fields from both structures via one pointer,
|
|
and the compiler doesn't change the order of write instructions
|
|
in relation to read instructions.
|
|
|
|
If we don't use memory write instructions to shared memory in
|
|
some local code, and we use only reading instructions (read only),
|
|
then probably it's safe to use pointers to different types for reading.
|
|
*/
|
|
|
|
|
|
|
|
#ifdef PPMD_32BIT
|
|
|
|
#define Ppmd_Ref_Type(type) type *
|
|
#define Ppmd_GetRef(p, ptr) (ptr)
|
|
#define Ppmd_GetPtr(p, ptr) (ptr)
|
|
#define Ppmd_GetPtr_Type(p, ptr, note_type) (ptr)
|
|
|
|
#else
|
|
|
|
#define Ppmd_Ref_Type(type) UInt32
|
|
#define Ppmd_GetRef(p, ptr) ((UInt32)((Byte *)(ptr) - (p)->Base))
|
|
#define Ppmd_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
|
|
#define Ppmd_GetPtr_Type(p, offs, type) ((type *)Ppmd_GetPtr(p, offs))
|
|
|
|
#endif // PPMD_32BIT
|
|
|
|
|
|
typedef Ppmd_Ref_Type(CPpmd_State) CPpmd_State_Ref;
|
|
typedef Ppmd_Ref_Type(void) CPpmd_Void_Ref;
|
|
typedef Ppmd_Ref_Type(Byte) CPpmd_Byte_Ref;
|
|
|
|
|
|
/*
|
|
#ifdef MY_CPU_LE_UNALIGN
|
|
// the unaligned 32-bit access latency can be too large, if the data is not in L1 cache.
|
|
#define Ppmd_GET_SUCCESSOR(p) ((CPpmd_Void_Ref)*(const UInt32 *)(const void *)&(p)->Successor_0)
|
|
#define Ppmd_SET_SUCCESSOR(p, v) *(UInt32 *)(void *)(void *)&(p)->Successor_0 = (UInt32)(v)
|
|
|
|
#else
|
|
*/
|
|
|
|
/*
|
|
We can write 16-bit halves to 32-bit (Successor) field in any selected order.
|
|
But the native order is more consistent way.
|
|
So we use the native order, if LE/BE order can be detected here at compile time.
|
|
*/
|
|
|
|
#ifdef MY_CPU_BE
|
|
|
|
#define Ppmd_GET_SUCCESSOR(p) \
|
|
( (CPpmd_Void_Ref) (((UInt32)(p)->Successor_0 << 16) | (p)->Successor_1) )
|
|
|
|
#define Ppmd_SET_SUCCESSOR(p, v) { \
|
|
(p)->Successor_0 = (UInt16)(((UInt32)(v) >> 16) /* & 0xFFFF */); \
|
|
(p)->Successor_1 = (UInt16)((UInt32)(v) /* & 0xFFFF */); }
|
|
|
|
#else
|
|
|
|
#define Ppmd_GET_SUCCESSOR(p) \
|
|
( (CPpmd_Void_Ref) ((p)->Successor_0 | ((UInt32)(p)->Successor_1 << 16)) )
|
|
|
|
#define Ppmd_SET_SUCCESSOR(p, v) { \
|
|
(p)->Successor_0 = (UInt16)((UInt32)(v) /* & 0xFFFF */); \
|
|
(p)->Successor_1 = (UInt16)(((UInt32)(v) >> 16) /* & 0xFFFF */); }
|
|
|
|
#endif
|
|
|
|
// #endif
|
|
|
|
|
|
#define PPMD_SetAllBitsIn256Bytes(p) \
|
|
{ size_t z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \
|
|
p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }}
|
|
|
|
EXTERN_C_END
|
|
|
|
#endif
|