Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,4 @@

#ifndef CONFIG_APU_N_BUFSIZE
#define CONFIG_APU_N_BUFSIZE 32768
#endif
#endif
80 changes: 18 additions & 62 deletions fabric.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,67 +10,14 @@
#include "lru.h"
#endif


PGB_FUNC void pgf_timer_update_internal(struct pgf_userdata_t* __restrict ud, word ticks)
{
//if(!(ud->TIMER_CNT & 4))
// return;

var nres = ticks + ud->TIMER_SUB;
// 0, 4, 16, 64

var ncnt = 1 << ((ud->TIMER_CNT & 3) << 1);
if(ncnt & 1)
ncnt <<= 8;

/*
var ncnt;
switch(ud->TIMER_CNT & 3)
{
case 0:
ncnt = 256;
break;
case 1:
ncnt = 4;
break;
case 2:
ncnt = 16;
break;
case 3:
ncnt = 64;
break;

default:
__builtin_unreachable();
}
*/


if(nres >= ncnt)
{
var tv = ud->TIMER_ACCUM;

do
{
if((++tv) >> 8)
{
tv = ud->TIMER_LOAD;
ud->mb->IF |= 4;
}

nres -= ncnt;
}
while(nres >= ncnt);

ud->TIMER_ACCUM = tv;
}

ud->TIMER_SUB = nres;
}

PGB_FUNC const r8* pgf_resolve_ROM(void* userdata, word addr, word bank)
{
#if CONFIG_ENABLE_LRU
return pgf_resolve_ROM_internal(userdata, addr, bank);
#else
USE_UD;
return ud->mb->mi->ROMBASE + 0x4000 * bank + (addr & 0x3FFF);
#endif
}

//#include "profi.h"
Expand Down Expand Up @@ -193,30 +140,39 @@ PGB_FUNC word pgf_cb_IO_(void* userdata, word addr, word data, word type)
{
if(type)
{
ud->TIMER_ACCUM = data;
ud->TIMER_ACCUM = data << 8;
return data;
}

return ud->TIMER_ACCUM;
return ud->TIMER_ACCUM >> 8;
}
else if(reg == 6)
{
if(type)
{
ud->TIMER_LOAD = data;
ud->TIMER_LOAD = data << 8;
return data;
}

return ud->TIMER_LOAD;
return ud->TIMER_LOAD >> 8;
}
else if(reg == 7)
{
if(type)
{
if(!(ud->TIMER_CNT & 4))
{
ud->TIMER_SUB = -2;
}
//ud->TIMER_ACCUM = ud->TIMER_LOAD;
ud->TIMER_CNT = data & 7;

const static uint8_t TIMER_INC_RATE[] = {
0, 0, 0, 0,
1, 64, 16, 4
};

ud->TIMER_INC = TIMER_INC_RATE[data & 7];
return data;
}

Expand Down
26 changes: 18 additions & 8 deletions fabric.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ struct pgf_userdata_t
var JOYP_RAW; // A is $01, Right is $10
var JOYP;

var TIMER_ACCUM; // bits 8-15 contain visible timer
var TIMER_INC; // how much to increment timer
var TIMER_SUB;
var TIMER_CNT;
var TIMER_ACCUM;
var TIMER_LOAD;

var SB;
Expand All @@ -46,12 +47,15 @@ PGB_FUNC r32 pgf_cb_BOOTROM(void* userdata, r32 addr, r32 data, word type);
const r8* pgf_cb_ROM_LRU_(void* userdata, word addr, word bank);
#endif

static inline void pgf_timer_update(struct pgf_userdata_t* __restrict ud, word ticks)
static inline void pgf_timer_update(struct pgf_userdata_t* __restrict ud, word cycles)
{
if(!(ud->TIMER_CNT & 4))
return;

pgf_timer_update_internal(ud, ticks);
ud->TIMER_ACCUM += ud->TIMER_INC * cycles;
if UNLIKELY(ud->TIMER_ACCUM >= 0x10000)
{
ud->mb->IF |= 4;
word remainder = 0x10000 - ud->TIMER_LOAD;
ud->TIMER_ACCUM = ud->TIMER_LOAD + ((ud->TIMER_INC * cycles) % remainder);
}
}

static inline const r8* pgf_resolve_ROM_internal(void* userdata, word addr, word bank)
Expand All @@ -67,9 +71,15 @@ static inline const r8* pgf_resolve_ROM_internal(void* userdata, word addr, word
if(ud->mb->mi->ROM)
#endif
{
res = ud->mb->mi->ROM[bank];
if(res)
#if CONFIG_ENABLE_LRU
res = ud->mb->mi->ROM[bank];
if (res)
return &res[addr & 0x3FFF];
#else
res = ud->mb->mi->ROMBASE + 0x4000 * bank;
return &res[addr & 0x3FFF];
#endif

}

#if CONFIG_ENABLE_LRU
Expand Down
3 changes: 3 additions & 0 deletions mi.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ struct mb_mi_cache
struct mi_dispatch
{
const r8* __restrict const * __restrict ROM;
#if !CONFIG_ENABLE_LRU
const r8* __restrict ROMBASE;
#endif
r8* __restrict WRAM;
r8* __restrict VRAM;
r8* __restrict SRAM;
Expand Down
82 changes: 65 additions & 17 deletions microcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "microcode.h"
#include "dbg.h"
#include "fabric.h"


#define self mb_state* __restrict mb
Expand Down Expand Up @@ -56,13 +57,21 @@ PGB_FUNC static const r8* mch_resolve_mic_r_direct_read(const self, word r_addr)
{
if(r_addr < MICACHE_R_VALUE(0x4000))
{
ret = mi->ROM[0];
#if CONFIG_ENABLE_LRU
ret = mi->ROM[0];
#else
ret = mi->ROMBASE;
#endif
if(ret)
return &ret[r_addr << MICACHE_R_BITS];
}
else
{
ret = mi->ROM[mi->BANK_ROM];
#if CONFIG_ENABLE_LRU
ret = mi->ROM[mi->BANK_ROM];
#else
ret = mi->ROMBASE + 0x4000 * mi->BANK_ROM;
#endif
if(ret)
{
r_addr &= MICACHE_R_VALUE(0x3FFF);
Expand Down Expand Up @@ -240,7 +249,7 @@ PGB_FUNC static word mch_memory_dispatch_read_fexx_ffxx(const self, word addr)
{
var hm = addr & 0xFF;

if(hm != 0xFF)
if LIKELY(hm != 0xFF)
{
USE_MI;

Expand All @@ -262,7 +271,7 @@ PGB_FUNC static void mch_memory_dispatch_write_fexx_ffxx(self, word addr, word d
{
var hm = addr & 0xFF;

if(hm != 0xFF)
if LIKELY(hm != 0xFF)
{
USE_MI;

Expand Down Expand Up @@ -301,7 +310,7 @@ PGB_FUNC ATTR_HOT static word mch_memory_dispatch_read_(self, word addr)
return *ptr;
}

if(addr < 0xFE00)
if UNLIKELY(addr < 0xFE00)
{
addr -= 0x2000;
goto wram_read;
Expand Down Expand Up @@ -366,7 +375,7 @@ PGB_FUNC ATTR_HOT static inline word mch_memory_fetch_decode_1(self, word addr)
return *ptr;
}

if(addr < 0xFE00)
if UNLIKELY(addr < 0xFE00)
{
addr -= 0x2000;
goto wram_read;
Expand Down Expand Up @@ -426,10 +435,30 @@ PGB_FUNC static word mch_memory_fetch_decode_2(self, word addr)
// Fetch one byte from PC, incrementing it as well
PGB_FUNC ATTR_HOT static word mch_memory_fetch_PC(self)
{
var res;
word addr = mb->PC;
mb->PC = (addr + 1) & 0xFFFF;
mb->PC = (addr + 1);

#if CONFIG_ENABLE_LRU
mb->PC &= 0xFFFF;
res = mch_memory_fetch_decode_1(mb, addr);
#else
if LIKELY(addr < 0x8000)
{
USE_MI;

const r8* __restrict rom = (addr < 0x4000)
? mi->ROMBASE
: (mi->ROMBASE + 0x4000 * mi->BANK_ROM);
res = rom[addr & 0x3FFF];
}
else
{
mb->PC &= 0xFFFF;
res = mch_memory_fetch_decode_1(mb, addr);
}
#endif

var res = mch_memory_fetch_decode_1(mb, addr);
DBGF("- /M1 %04X <> %02X\n", addr, res);
return res;
}
Expand All @@ -438,11 +467,24 @@ PGB_FUNC ATTR_HOT static word mch_memory_fetch_PC(self)
PGB_FUNC ATTR_HOT static word mch_memory_fetch_PC_2(self)
{
word addr = mb->PC;
mb->PC = (addr + 2) & 0xFFFF;
mb->PC += 2;

word resp = mch_memory_fetch_decode_2(mb, addr);
DBGF("- /M2 %04X <> %04X\n", addr, resp);
return resp;
if (addr < 0x8000 && (addr % 0x4000 != 0x3FFF) && !CONFIG_ENABLE_LRU)
{
USE_MI;
const r8* __restrict rom = (addr < 0x4000)
? mi->ROMBASE
: (mi->ROMBASE + 0x4000 * mi->BANK_ROM);
return *(r16*)&rom[addr % 0x4000];
}
else
{
mb->PC &= 0xFFFF;

word resp = mch_memory_fetch_decode_2(mb, addr);
DBGF("- /M2 %04X <> %04X\n", addr, resp);
return resp;
}
}

#pragma endregion
Expand Down Expand Up @@ -989,18 +1031,24 @@ PGB_FUNC ATTR_HOT word mb_exec(self)
case 3: // JR e8
generic_jr:
{
var PC = mb->PC;
data_wide = mch_memory_fetch_PC(mb);
var PC = mb->PC;

// Wedge if unbreakable spinloop is detected
// TODO: unfuck this statement
if(data_wide == 0xFE && ((!mb->IME && !mb->IME_ASK) || (!mb->IE && !(mb->IF & 0x1F))))
return 0; // wedge until NMI
if(data_wide == 0xFE)
{
if ((!mb->IME && !mb->IME_ASK) || (!mb->IE && !(mb->IF & 0x1F)))
return 0; // wedge until NMI

// XXX optimization hack -- 1 fps gain on cv2
ncycles += 20;
}

if(data_wide >= 0x80)
data_wide |= 0xFF00;

mb->PC = (data_wide + PC + 1) & 0xFFFF;
mb->PC = (data_wide + PC) & 0xFFFF;

ncycles += 2; // parallel add + fetch
goto generic_fetch;
Expand Down Expand Up @@ -1315,7 +1363,7 @@ PGB_FUNC ATTR_HOT word mb_exec(self)
return 0;

case 1: // MOV
if(IR != 0x76)
if LIKELY(IR != 0x76)
{
instr_MOV:
{
Expand Down
9 changes: 2 additions & 7 deletions pgb_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,14 @@ static inline word pgb_main_tick(mb_state* __restrict mb, vbool* ticked)
if(ticked)
*ticked = 1;
}
else if(mb->HALTING)
else // mb->HALTING
{
if(!mb->IR.high)
mb->IR.high = 1
mb->IR.high = 1;

if(ticked)
*ticked = 0;
}
else // ???
{
if(ticked)
*ticked = 0;
}

return cycles;
}
13 changes: 13 additions & 0 deletions types.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@
//#define COMPILER_VARIABLE_BARRIER(var) (void)(var)
#define COMPILER_VARIABLE_BARRIER(var) __asm volatile(""::"r"(var))

#if defined(__GNUC__) || defined(__clang__)
#define LIKELY(x) (__builtin_expect(!!(x), 1))
#define UNLIKELY(x) (__builtin_expect(!!(x), 0))
#else
#define LIKELY(x) (x)
#define UNLIKELY(x) (x)
#endif

#if defined(__GNUC__) || defined(__clang__)
#define LIKELY_P(x, p) (__builtin_expect_with_probability(!!(x), 1, p))
#else
#define LIKELY_P(x, p) (x)
#endif

#if PPU_IS_MONOCHROME
typedef unsigned char pixel_t;
Expand Down