mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-22 22:24:16 -04:00
ks_nes_draw: slight score improvements, document draw struct members (best guess)
This commit is contained in:
+126
-44
@@ -13,6 +13,15 @@ extern "C" {
|
||||
#define KS_NES_WIDTH 256
|
||||
#define KS_NES_HEIGHT 228
|
||||
|
||||
|
||||
#define KS_NES_SCANLINE_COUNT 240 // 228 visible + 8 pre-render + 8 post-render
|
||||
#define KS_NES_SCANLINE_SPRITE_OVERDRAW_COUNT (KS_NES_SCANLINE_COUNT + 32) // 272
|
||||
|
||||
#define KS_NES_CENTER_X (KS_NES_WIDTH / 2)
|
||||
#define KS_NES_CENTER_Y (KS_NES_SCANLINE_SPRITE_OVERDRAW_COUNT / 2)
|
||||
|
||||
#define KS_NES_OAM_TABLE_SIZE 64
|
||||
|
||||
#define CHR_TO_I8_BUF_SIZE 0x100000
|
||||
#define KS_NES_NESFILE_HEADER_SIZE 0x10
|
||||
#define KS_NES_PRGROM_SIZE 0x80000 // 512kb for MMC3
|
||||
@@ -31,9 +40,44 @@ extern "C" {
|
||||
#define KS_NES_BYTES_PER_KB (1024)
|
||||
#define KS_NES_TO_KB(b) ((f32)b * (1.0f / (f32)KS_NES_BYTES_PER_KB))
|
||||
|
||||
#define KS_NES_PPU_STATUS_FLG_SPRITE_OVERFLOW (1 << 5)
|
||||
#define KS_NES_PPU_STATUS_FLG_SPRITE_ZERO_HIT (1 << 6)
|
||||
#define KS_NES_PPU_STATUS_FLG_VBLANK (1 << 7)
|
||||
// NES PPU Control Register ($2000) flags
|
||||
#define KS_NES_PPU_CTRL_NAMETABLE_MASK 0x03 // Nametable select (0-3)
|
||||
#define KS_NES_PPU_CTRL_NAMETABLE_0 0x00 // Nametable at $2000
|
||||
#define KS_NES_PPU_CTRL_NAMETABLE_1 0x01 // Nametable at $2400
|
||||
#define KS_NES_PPU_CTRL_NAMETABLE_2 0x02 // Nametable at $2800
|
||||
#define KS_NES_PPU_CTRL_NAMETABLE_3 0x03 // Nametable at $2C00
|
||||
|
||||
#define KS_NES_PPU_CTRL_VRAM_INCREMENT 0x04 // VRAM address increment (0=add 1 across, 1=add 32 down)
|
||||
#define KS_NES_PPU_CTRL_SPRITE_PATTERN 0x08 // Sprite pattern table for 8x8 sprites (0=$0000, 1=$1000)
|
||||
#define KS_NES_PPU_CTRL_BG_PATTERN 0x10 // Background pattern table (0=$0000, 1=$1000)
|
||||
#define KS_NES_PPU_CTRL_SPRITE_SIZE 0x20 // Sprite size (0=8x8, 1=8x16)
|
||||
#define KS_NES_PPU_CTRL_MASTER_SLAVE 0x40 // PPU master/slave select
|
||||
#define KS_NES_PPU_CTRL_NMI_ENABLE 0x80 // Generate NMI at start of vertical blanking
|
||||
|
||||
// Sprite sizes
|
||||
#define KS_NES_PPU_CTRL_SPRITE_SIZE_8x8 0x00 // 8x8 sprite size
|
||||
#define KS_NES_PPU_CTRL_SPRITE_SIZE_8x16 0x20 // 8x16 sprite size
|
||||
|
||||
// NES PPU Mask Register ($2001) flags
|
||||
#define KS_NES_PPU_MASK_GREYSCALE 0x01 // Greyscale mode
|
||||
#define KS_NES_PPU_MASK_SHOW_BG_LEFT 0x02 // Show background in leftmost 8 pixels
|
||||
#define KS_NES_PPU_MASK_SHOW_SPRITES_LEFT 0x04 // Show sprites in leftmost 8 pixels
|
||||
#define KS_NES_PPU_MASK_SHOW_BG 0x08 // Enable background rendering
|
||||
#define KS_NES_PPU_MASK_SHOW_SPRITES 0x10 // Enable sprite rendering
|
||||
#define KS_NES_PPU_MASK_EMPHASIZE_RED 0x20 // Emphasize red channel
|
||||
#define KS_NES_PPU_MASK_EMPHASIZE_GREEN 0x40 // Emphasize green channel
|
||||
#define KS_NES_PPU_MASK_EMPHASIZE_BLUE 0x80 // Emphasize blue channel
|
||||
|
||||
// NES PPU Status Register ($2002) flags
|
||||
#define KS_NES_PPU_STATUS_FLG_SPRITE_OVERFLOW (1 << 5) // 0x20
|
||||
#define KS_NES_PPU_STATUS_FLG_SPRITE_ZERO_HIT (1 << 6) // 0x40
|
||||
#define KS_NES_PPU_STATUS_FLG_VBLANK (1 << 7) // 0x80
|
||||
|
||||
// Combined masks used in the codebase
|
||||
// All color modification bits (greyscale + RGB emphasis)
|
||||
#define KS_NES_PPU_MASK_COLOR_EFFECTS (KS_NES_PPU_MASK_GREYSCALE | KS_NES_PPU_MASK_EMPHASIZE_RED | KS_NES_PPU_MASK_EMPHASIZE_GREEN | KS_NES_PPU_MASK_EMPHASIZE_BLUE) // 0xE1
|
||||
// Sprites enabled + leftmost sprites
|
||||
#define KS_NES_PPU_MASK_SPRITES_COMBINED (KS_NES_PPU_MASK_SHOW_SPRITES_LEFT | KS_NES_PPU_MASK_SHOW_SPRITES) // 0x14
|
||||
|
||||
// Timer IRQ control register @ 0x4022
|
||||
#define KS_NES_FDS_TIMER_CTRL_FLG_IRQ_REPEAT (1 << 0) // 0 = don't repeat, 1 = repeat
|
||||
@@ -53,50 +97,88 @@ extern "C" {
|
||||
#define KS_NES_FDS_CTRL_FLG_CRC_ENABLE (1 << 6) // 0 = disable/reset, 1 = enable
|
||||
#define KS_NES_FDS_CTRL_FLG_INTERRUPT_ENABLE (1 << 7) // 1 = generate IRQ every time byte transfer flag is raised
|
||||
|
||||
typedef struct _0B40_struct {
|
||||
u8* _00;
|
||||
u8* _04;
|
||||
// u8* _08;
|
||||
u8 _08[4]; // idk how many elements this should be
|
||||
u32 _0C;
|
||||
u32 _10;
|
||||
u32 _14;
|
||||
u8 _18;
|
||||
u8 _19;
|
||||
u8 _1A;
|
||||
u8 _1B;
|
||||
u8 _1C;
|
||||
u8 _1D;
|
||||
u8 _1E;
|
||||
u8 _1F;
|
||||
} B40_struct; // size == 0x20
|
||||
// OAM Tile/Index Flags
|
||||
#define KS_NES_OAM_TILE_BANK 0x01
|
||||
#define KS_NES_OAM_TILE_IDX 0xFE
|
||||
|
||||
typedef struct _0340_struct {
|
||||
u8 _00[0x20];
|
||||
} _0340_struct; // size = 0x20
|
||||
// OAM Attribute Flags
|
||||
#define KS_NES_OAM_ATTR_PALETTE_MASK 0x03
|
||||
#define KS_NES_OAM_ATTR_PRIORITY (1 << 5) // 0x20, 0 = in front of background, 1 = behind background
|
||||
#define KS_NES_OAM_ATTR_FLIP_HORIZONTAL (1 << 6) // 0x40, 0 = normal, 1 = flip horizontally
|
||||
#define KS_NES_OAM_ATTR_FLIP_VERTICAL (1 << 7) // 0x80, 0 = normal, 1 = flip vertically
|
||||
|
||||
typedef struct ksNesWorkPriv2940_struct {
|
||||
u8 _00;
|
||||
u8 _01;
|
||||
u8 _02;
|
||||
u8 _03;
|
||||
} ksNesWorkPriv2940_struct;
|
||||
// Misc
|
||||
#define KS_NES_SPRITES_PER_SCANLINE 8
|
||||
|
||||
typedef struct ksNesCommonWorkPriv {
|
||||
/* 0x0000 */ u8 _0000[0x200];
|
||||
/* 0x0200 */ u8 _0200[0xF0];
|
||||
/* 0x02F0 */ u8 _pad_02F0[0x10];
|
||||
/* 0x0300 */ u8 _0300[0x40];
|
||||
/* 0x0340 */ _0340_struct _0340[0x40];
|
||||
/* 0x0B40 */ B40_struct _0B40[240];
|
||||
/* 0x2940 */ ksNesWorkPriv2940_struct _2940[64];
|
||||
/* 0x2A40 */ u8 _2A40[0x800];
|
||||
/* 0x3240 */ u8 _3240[0x4800];
|
||||
/* 0x7840 */ u8 _7840[0x1400];
|
||||
/* 0x8E40 */ u8 _8E40[0x80]; // 4x16 texture IA8
|
||||
/* 0x8EC0 */ u8 _8EC0[0x28]; // 8x4 texture IA8
|
||||
// Mapper definitions
|
||||
#define KS_NES_MAPPER_NROM 0
|
||||
#define KS_NES_MAPPER_MMC1 1
|
||||
#define KS_NES_MAPPER_UxROM 2
|
||||
#define KS_NES_MAPPER_CNROM 3
|
||||
#define KS_NES_MAPPER_MMC3 4
|
||||
#define KS_NES_MAPPER_MMC5 5
|
||||
#define KS_NES_MAPPER_MMC2 9
|
||||
#define KS_NES_MAPPER_MMC4 10
|
||||
|
||||
#define KS_NES_MAPPER_KONAMI_VRC6A 24
|
||||
#define KS_NES_MAPPER_KONAMI_VRC6B 26
|
||||
|
||||
// Emulator flags
|
||||
#define KS_NES_FLAG_NINES_OVER_MODE (1 << 13) // 0x2000, enables "nines over" mode which allows drawing more than 8 sprites per scanline
|
||||
|
||||
typedef struct ksNesPPUScanlineState {
|
||||
u8* nametable_ptrs[2];
|
||||
// Either chr_bank_sprite or chr_bank_bg_mmc3 is used depending on mapper type and CPU cycle
|
||||
union {
|
||||
u8 chr_bank_sprite[4]; // lower four bytes are unused when not in MMC3 mode
|
||||
u32 chr_bank_bg_mmc3[2]; // used in ksNesDrawMakeBGIndTex when the scanline column is >= 9.
|
||||
};
|
||||
|
||||
u32 chr_bank_bg[2];
|
||||
u8 ppu_ctrl;
|
||||
u8 ppumask_flags;
|
||||
u8 fine_x_and_next;
|
||||
u8 vram_addr_coarse_x;
|
||||
u8 vram_addr_y;
|
||||
|
||||
// MMC5-only state
|
||||
u8 mmc5_ext_mode;
|
||||
u8 chr_bank_ext_upper_sprite;
|
||||
u8 chr_bank_ext_upper_bg;
|
||||
} ksNesPPUScanlineState; // size == 0x20
|
||||
|
||||
typedef struct ksNesSpriteQuadData {
|
||||
u8 y_and_v_pairs[32]; // Pairs of (Y position, texture V coord) for quad segments
|
||||
// Each quad segment uses 4 bytes: y_top, v_top, y_bottom, v_bottom
|
||||
// Supports up to 8 quad segments per sprite
|
||||
} ksNesSpriteQuadData; // size = 0x20
|
||||
|
||||
typedef struct ksNesOAMEntry {
|
||||
u8 y_pos;
|
||||
u8 tile_index;
|
||||
u8 attributes;
|
||||
u8 x_pos;
|
||||
} ksNesOAMEntry;
|
||||
|
||||
typedef struct ksNesDrawCtx {
|
||||
/* 0x0000 */ union {
|
||||
u8 sprite_scanline_limit[KS_NES_SCANLINE_COUNT]; // tracks the number of sprites that have been drawn on each scanline
|
||||
u8 scanline_y_coords[2 * 256]; // tracks the Y coordinate of the top & bottom of each scanline
|
||||
};
|
||||
|
||||
/* 0x0200 */ u8 mmc2_scanline_latch_tiles[KS_NES_SCANLINE_COUNT]; // tracks which tiles should be accessible on each scanline based on MMC2 latch settings
|
||||
/* 0x02F0 */ u8 _pad_02F0[0x10]; // might be included in mmc2_scanline_latch_tiles
|
||||
/* 0x0300 */ u8 sprite_vertex_count[KS_NES_OAM_TABLE_SIZE];
|
||||
/* 0x0340 */ ksNesSpriteQuadData sprite_quad_data[KS_NES_OAM_TABLE_SIZE];
|
||||
/* 0x0B40 */ ksNesPPUScanlineState ppu_scanline_regs[KS_NES_SCANLINE_COUNT];
|
||||
/* 0x2940 */ ksNesOAMEntry OAMTable[KS_NES_OAM_TABLE_SIZE];
|
||||
/* 0x2A40 */ u8 post_process_lut[0x800];
|
||||
/* 0x3240 */ u8 bg_tile_index_texture[(36 * 256) * 2]; // IA8 texture, holds information about the background tile indices and pattern table data
|
||||
/* 0x7840 */ u8 bg_palette_attr_texture[(40 * 256) / 2]; // I4 texture, holds background palette attributes
|
||||
/* 0x8E40 */ u8 sprite_indirect_lut[(16 * 4) * 2]; // 4x16 texture IA8, handles indirect tex coords, for mirroring and sized sprites
|
||||
/* 0x8EC0 */ u8 sprite_chr_bank_lut[(5 * 4) * 2]; // 8x4 IA8 sprite CHR bank lookup table -- @ BUG - this is setup as a 5x4 IA8 texture, but gets loaded as 8x4.
|
||||
/* 0x8EE8 */ Mtx34 draw_mtx;
|
||||
} ksNesCommonWorkPriv;
|
||||
} ksNesDrawCtx;
|
||||
|
||||
typedef struct ksNesCommonWorkObj {
|
||||
/* 0x0000 */ u8* nesromp;
|
||||
@@ -117,7 +199,7 @@ typedef struct ksNesCommonWorkObj {
|
||||
/* 0x003C */ u8 _003C[0x0048 - 0x003C];
|
||||
/* 0x0048 */ size_t prg_size;
|
||||
/* 0x004C */ u8 _004C[0x0060 - 0x004C];
|
||||
/* 0x0060 */ ksNesCommonWorkPriv work_priv;
|
||||
/* 0x0060 */ ksNesDrawCtx draw_ctx;
|
||||
} ksNesCommonWorkObj;
|
||||
|
||||
typedef struct ksNesStateObj {
|
||||
|
||||
@@ -2134,8 +2134,8 @@ static int famicom_rom_load() {
|
||||
if (reset_res != 0) {
|
||||
OSReport("err code=%d (0x%x), %x,%x,%x,%x,%x,%x\n",
|
||||
reset_res, reset_res, famicomCommon.wp, famicomCommon.sp,
|
||||
famicomCommon.wp->work_priv._0000, famicomCommon.wp->work_priv._0B40,
|
||||
famicomCommon.wp->work_priv._2A40, famicomCommon.sp->ppu_chr_banks
|
||||
famicomCommon.wp->draw_ctx.sprite_scanline_limit, famicomCommon.wp->draw_ctx.ppu_scanline_regs,
|
||||
famicomCommon.wp->draw_ctx.post_process_lut, famicomCommon.sp->ppu_chr_banks
|
||||
);
|
||||
OSReport("NES emu reset failed!!");
|
||||
}
|
||||
@@ -2479,7 +2479,7 @@ extern void famicom_1frame() {
|
||||
}
|
||||
|
||||
if (nines_over_mode) {
|
||||
flags |= 0x2000;
|
||||
flags |= KS_NES_FLAG_NINES_OVER_MODE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -753,7 +753,7 @@ void* ksNesMapperInitFuncTbl[185][5] = {
|
||||
ksNesLinecntIrqDefault,
|
||||
ksNesLinecntIrqDefault,
|
||||
ksNesLinecntIrqDefault,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@@ -2318,13 +2318,13 @@ void ksNesDrawMakeOBJIndTex(ksNesCommonWorkObj* wp) {
|
||||
#define TO_IND1(x) (((x) / 4) * 32) + (((x) % 4) * 8)
|
||||
#define TO_IND2(x) (((x) / 4) * 32) + (((x) % 4) * 2)
|
||||
for (j = 0; j < 4; j++) {
|
||||
wp->work_priv._8E40[TO_IND1(i) + TO_IND2(j)] = (i >> 3) & 1;
|
||||
wp->work_priv._8E40[TO_IND1(i) + TO_IND2(j) + 1] = array[i & 7] << 2;
|
||||
wp->draw_ctx.sprite_indirect_lut[TO_IND1(i) + TO_IND2(j)] = (i >> 3) & 1;
|
||||
wp->draw_ctx.sprite_indirect_lut[TO_IND1(i) + TO_IND2(j) + 1] = array[i & 7] << 2;
|
||||
}
|
||||
}
|
||||
#undef TO_IND1
|
||||
#undef TO_IND2
|
||||
DCFlushRangeNoSync(wp->work_priv._8E40, sizeof(wp->work_priv._8E40));
|
||||
DCFlushRangeNoSync(wp->draw_ctx.sprite_indirect_lut, sizeof(wp->draw_ctx.sprite_indirect_lut));
|
||||
}
|
||||
|
||||
void ksNesDrawMakeOBJIndTexMMC5(ksNesCommonWorkObj* wp) {
|
||||
@@ -2333,13 +2333,13 @@ void ksNesDrawMakeOBJIndTexMMC5(ksNesCommonWorkObj* wp) {
|
||||
for (u32 i = 0; i < 16; i++) {
|
||||
for (u32 j = 0; j < 4; j++) {
|
||||
static const u8 array[] = { 0x00, 0x01, 0x02, 0x03 };
|
||||
wp->work_priv._8E40[TO_IND1(i) + TO_IND2(j)] = 0;
|
||||
wp->work_priv._8E40[TO_IND1(i) + TO_IND2(j) + 1] = array[i % 4] * 4;
|
||||
wp->draw_ctx.sprite_indirect_lut[TO_IND1(i) + TO_IND2(j)] = 0;
|
||||
wp->draw_ctx.sprite_indirect_lut[TO_IND1(i) + TO_IND2(j) + 1] = array[i % 4] * 4;
|
||||
}
|
||||
}
|
||||
#undef TO_IND1
|
||||
#undef TO_IND2
|
||||
DCFlushRangeNoSync(&wp->work_priv._8E40, sizeof(wp->work_priv._8E40));
|
||||
DCFlushRangeNoSync(&wp->draw_ctx.sprite_indirect_lut, sizeof(wp->draw_ctx.sprite_indirect_lut));
|
||||
}
|
||||
|
||||
void ksNesConvertChrToI8(ksNesCommonWorkObj* wp, const u8* data, u32 flags) {
|
||||
@@ -2650,8 +2650,8 @@ int ksNesReset(ksNesCommonWorkObj* wp, ksNesStateObj* sp, u32 flags, u8* chrramp
|
||||
|
||||
// looks like we're checking memory alignment.
|
||||
// maybe done for performance reasons?
|
||||
if ((uint)wp & 0x1f || (uint)sp & 0x1f || (uint)&wp->work_priv & 0x1f || (uint)&wp->work_priv._0B40 & 0x1f ||
|
||||
(uint)sp->ppu_chr_banks & 0x03 || (uint)&wp->work_priv._2A40 & 0x1f) {
|
||||
if ((uint)wp & 0x1f || (uint)sp & 0x1f || (uint)&wp->draw_ctx & 0x1f || (uint)&wp->draw_ctx.ppu_scanline_regs & 0x1f ||
|
||||
(uint)sp->ppu_chr_banks & 0x03 || (uint)&wp->draw_ctx.post_process_lut & 0x1f) {
|
||||
return 0x515;
|
||||
}
|
||||
|
||||
@@ -2673,7 +2673,7 @@ int ksNesReset(ksNesCommonWorkObj* wp, ksNesStateObj* sp, u32 flags, u8* chrramp
|
||||
|
||||
if (flags & 1) {
|
||||
// temporarily save the work ram state.
|
||||
memcpy(&wp->work_priv._0000, &sp->wram, KS_NES_WRAM_SIZE);
|
||||
memcpy(&wp->draw_ctx, &sp->wram, KS_NES_WRAM_SIZE);
|
||||
}
|
||||
|
||||
// zero out the state struct.
|
||||
@@ -2681,7 +2681,7 @@ int ksNesReset(ksNesCommonWorkObj* wp, ksNesStateObj* sp, u32 flags, u8* chrramp
|
||||
|
||||
if (flags & 1) {
|
||||
// restore the previously saved work ram state.
|
||||
memcpy(&sp->wram, &wp->work_priv._0000, KS_NES_WRAM_SIZE);
|
||||
memcpy(&sp->wram, &wp->draw_ctx, KS_NES_WRAM_SIZE);
|
||||
} else {
|
||||
// fill ram with a predetermined pattern.
|
||||
|
||||
@@ -2696,7 +2696,7 @@ int ksNesReset(ksNesCommonWorkObj* wp, ksNesStateObj* sp, u32 flags, u8* chrramp
|
||||
}
|
||||
|
||||
// zero out the private work struct
|
||||
memset(&wp->work_priv, 0, sizeof(ksNesCommonWorkPriv));
|
||||
memset(&wp->draw_ctx, 0, sizeof(ksNesDrawCtx));
|
||||
|
||||
for (i = 0; i < 0x18; i++) {
|
||||
sp->ppu_chr_bank_pointers[i] = &sp->ppu_nametable_ram[table[i & 0xf] * 0x100];
|
||||
@@ -2731,7 +2731,7 @@ int ksNesReset(ksNesCommonWorkObj* wp, ksNesStateObj* sp, u32 flags, u8* chrramp
|
||||
// extract the chr ram/rom size from the ines header and convert it from 8k chunks to bytes.
|
||||
sp->chr_size = (size_t)sp->nesromp[0x5] << 0xd;
|
||||
|
||||
if ((sp->chr_size > 0x40000) && ((sp->mapper != 5 || (wp->chr_to_i8_buf_size < sp->chr_size << 2)))) {
|
||||
if ((sp->chr_size > 0x40000) && ((sp->mapper != KS_NES_MAPPER_MMC5 || (wp->chr_to_i8_buf_size < sp->chr_size << 2)))) {
|
||||
return 0x584;
|
||||
}
|
||||
|
||||
@@ -2744,7 +2744,7 @@ int ksNesReset(ksNesCommonWorkObj* wp, ksNesStateObj* sp, u32 flags, u8* chrramp
|
||||
|
||||
sp->reset_flags = flags;
|
||||
|
||||
if (sp->mapper == 5) {
|
||||
if (sp->mapper == KS_NES_MAPPER_MMC5) {
|
||||
ksNesDrawMakeOBJIndTexMMC5(wp);
|
||||
} else {
|
||||
ksNesDrawMakeOBJIndTex(wp);
|
||||
@@ -2763,8 +2763,8 @@ int ksNesReset(ksNesCommonWorkObj* wp, ksNesStateObj* sp, u32 flags, u8* chrramp
|
||||
}
|
||||
|
||||
for (i = 0; i < 0xf0; i++) {
|
||||
wp->work_priv._0B40[i]._00 = sp->ppu_nametable_pointers[0];
|
||||
wp->work_priv._0B40[i]._04 = sp->ppu_nametable_pointers[1];
|
||||
wp->draw_ctx.ppu_scanline_regs[i].nametable_ptrs[0] = sp->ppu_nametable_pointers[0];
|
||||
wp->draw_ctx.ppu_scanline_regs[i].nametable_ptrs[1] = sp->ppu_nametable_pointers[1];
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
@@ -2782,7 +2782,7 @@ int ksNesReset(ksNesCommonWorkObj* wp, ksNesStateObj* sp, u32 flags, u8* chrramp
|
||||
sp->chrramp = chrramp;
|
||||
sp->chr_size = 0x2000;
|
||||
|
||||
if (((flags & 8) != 0) && (sp->mapper == 5)) {
|
||||
if (((flags & 8) != 0) && (sp->mapper == KS_NES_MAPPER_MMC5)) {
|
||||
sp->chr_size = 0x20000;
|
||||
}
|
||||
|
||||
@@ -2793,7 +2793,7 @@ int ksNesReset(ksNesCommonWorkObj* wp, ksNesStateObj* sp, u32 flags, u8* chrramp
|
||||
} else {
|
||||
sp->chrramp = sp->prgromp + sp->prg_size;
|
||||
|
||||
if (sp->mapper == 5) {
|
||||
if (sp->mapper == KS_NES_MAPPER_MMC5) {
|
||||
for (uVar4 = 0; uVar4 < sp->chr_size; uVar4 = uVar4 + 0x10) {
|
||||
ksNesConvertChrToI8MMC5(wp, sp->chrramp + uVar4, uVar4 >> 4);
|
||||
}
|
||||
@@ -2902,11 +2902,11 @@ int ksNesReset(ksNesCommonWorkObj* wp, ksNesStateObj* sp, u32 flags, u8* chrramp
|
||||
Sound_SetE000(&sp->cpu_e000_ffff[0xe000]);
|
||||
|
||||
switch (sp->mapper) {
|
||||
case 5: // Nintendo's MMC5
|
||||
case KS_NES_MAPPER_MMC5: // Nintendo's MMC5
|
||||
Sound_SetMMC(0);
|
||||
break;
|
||||
case 24: // Konami's VRC6a
|
||||
case 26: // Konami's VRC6b
|
||||
case KS_NES_MAPPER_KONAMI_VRC6A: // Konami's VRC6a
|
||||
case KS_NES_MAPPER_KONAMI_VRC6B: // Konami's VRC6b
|
||||
Sound_SetMMC(1);
|
||||
Sound_Write(0x5015, 7, 0);
|
||||
break;
|
||||
@@ -2976,6 +2976,9 @@ void ksNesEmuFrame(ksNesCommonWorkObj* wp, ksNesStateObj* sp, u32 flags) {
|
||||
#define REGISTER_FLAG_OVERFLOW r21
|
||||
#define REGISTER_FLAG_NEGATIVE r22
|
||||
#define REGISTER_CYCLE_COUNT r25
|
||||
// r26 is reused for various purposes throughout the code
|
||||
#define REGISTER_SCANLINE_STATE r26
|
||||
#define REGISTER_TEMP_26 r26
|
||||
#define WRAM r31
|
||||
|
||||
// clang-format off
|
||||
@@ -3300,7 +3303,7 @@ asm void ksNesEmuFrameAsm(register ksNesCommonWorkObj* work_arg, register ksNesS
|
||||
stw r3, 0x08(r1)
|
||||
stw r4, 0x0c(r1)
|
||||
mr state_temp, state_arg
|
||||
addi r7, work_arg, work_arg->work_priv._0B40
|
||||
addi r7, work_arg, work_arg->draw_ctx.ppu_scanline_regs
|
||||
stw r7, 0xf4(r1)
|
||||
lwz r7, 0x14(r3)
|
||||
stw r7, 0xf0(r1)
|
||||
@@ -3476,7 +3479,7 @@ ksNesMainLoop1:
|
||||
|
||||
somewhere:
|
||||
lha r3, state_temp->ppu_scanline_counter
|
||||
clrlslwi. r7, REGISTER_CYCLE_COUNT, 30, 3
|
||||
clrlslwi. r7, REGISTER_CYCLE_COUNT, 30, 3 // r7 = (REGISTER_CYCLE_COUNT & 0x3) << 3
|
||||
lha r9, state_temp->cpu_cycles_per_vblank_scanline
|
||||
rlwimi REGISTER_CYCLE_COUNT, REGISTER_CYCLE_COUNT, 31, 30, 31
|
||||
beq LAB_8003b2f0
|
||||
@@ -3488,24 +3491,27 @@ somewhere:
|
||||
cmpwi r3, 0xf0
|
||||
bge LAB_8003b3b4
|
||||
|
||||
// r7 holds the cycle count % 4 multiplied by 8 to get the index to write the ppu_chr_banks into the scanline state's registers
|
||||
// this is done to accomodate different mapper implementations
|
||||
lwz r9, 0xf4(r1)
|
||||
slwi r8, r3, 5
|
||||
lwz r0, state_temp->ppu_chr_banks[0]
|
||||
lwz r10, state_temp->ppu_chr_banks[4]
|
||||
add r26, r8, r9
|
||||
stwux r0, r7, r26
|
||||
add REGISTER_SCANLINE_STATE, r8, r9 // r26 holds a pointer to the current scanline state struct
|
||||
stwux r0, r7, REGISTER_SCANLINE_STATE // store ((u32*)ppu_chr_banks)[0] to wp->draw_ctx.ppu_scanline_regs[state_temp->ppu_scanline_counter]._00[cycle_count & 3][0]
|
||||
andi. r0, REGISTER_CYCLE_COUNT, 0x1
|
||||
stw r10, 0x4(r7)
|
||||
stw r10, (ksNesPPUScanlineState.nametable_ptrs[1])(r7) // store ((u32*)ppu_chr_banks)[4] to wp->draw_ctx.ppu_scanline_regs[r3]._00[cycle_count & 3][1]
|
||||
bne ksNesMainLoop1
|
||||
|
||||
lhz r0, state_temp->ppu_register_cache[0]
|
||||
lbz r8, state_temp->_17C6
|
||||
lbz r7, state_temp->mapper
|
||||
rlwimi r0, r8, 0x9, 0x10, 0x11
|
||||
sth r0, 0x18(r26)
|
||||
cmpwi r7, 0x5
|
||||
sth r0, (ksNesPPUScanlineState.ppu_ctrl)(REGISTER_SCANLINE_STATE) // update both ppu_ctrl and ppumask_flags (PPUCTRL and PPUMASK regs)
|
||||
cmpwi r7, KS_NES_MAPPER_MMC5
|
||||
bne LAB_8003b19c
|
||||
|
||||
// handle MMC5 specific logic
|
||||
lbz r7, state_temp->_17C7
|
||||
stb r0, state_temp->_17C7
|
||||
xor r9, r7, r0
|
||||
@@ -3519,7 +3525,7 @@ somewhere:
|
||||
add r8, r8, r7
|
||||
stb r9, state_temp->_17C6
|
||||
rlwimi r0, r9, 0x9, 0x10, 0x11
|
||||
sth r0, 0x18(r26)
|
||||
sth r0, (ksNesPPUScanlineState.ppu_ctrl)(REGISTER_SCANLINE_STATE)
|
||||
add r9, r9, r7
|
||||
lswi r3, r8, 0x10
|
||||
addi r8, r8, 0x10
|
||||
@@ -3597,7 +3603,7 @@ LAB_8003afb0:
|
||||
cmpw r7, r0
|
||||
bne LAB_8003afb0
|
||||
LAB_8003afc4:
|
||||
stb r10, 0x1e(r26)
|
||||
stb r10, (ksNesPPUScanlineState.chr_bank_ext_upper_sprite)(REGISTER_SCANLINE_STATE)
|
||||
lbz r0, state_temp->ppu_register_cache[0]
|
||||
andi. r0, r0, 0x20
|
||||
beq LAB_8003b134
|
||||
@@ -3609,7 +3615,7 @@ LAB_8003afc4:
|
||||
cmpwi r7, 0x0
|
||||
bne LAB_8003b01c
|
||||
rlwinm r9, r9, 0x3, 0x0, 0x1c
|
||||
addi r6, r26, 0xf
|
||||
addi r6, REGISTER_SCANLINE_STATE, 0xf
|
||||
and r9, r9, r8
|
||||
addi r0, r6, 0x8
|
||||
LAB_8003b000:
|
||||
@@ -3622,7 +3628,7 @@ LAB_8003b000:
|
||||
b LAB_8003b138
|
||||
LAB_8003b01c:
|
||||
rlwinm r9, r9, 0x2, 0x0, 0x1d
|
||||
addi r6, r26, 0x10
|
||||
addi r6, REGISTER_SCANLINE_STATE, 0x10
|
||||
and r9, r9, r8
|
||||
addi r0, r6, 0x4
|
||||
LAB_8003b02c:
|
||||
@@ -3641,20 +3647,20 @@ LAB_8003b054:
|
||||
bne LAB_8003b0b0
|
||||
rlwinm r9, r9, 0x1, 0x0, 0x1e
|
||||
and r9, r9, r8
|
||||
stb r9, 0x12(r26)
|
||||
stb r9, 0x16(r26)
|
||||
stb r9, 0x12(REGISTER_SCANLINE_STATE)
|
||||
stb r9, 0x16(REGISTER_SCANLINE_STATE)
|
||||
addi r9, r9, 0x1
|
||||
stb r9, 0x13(r26)
|
||||
stb r9, 0x17(r26)
|
||||
stb r9, 0x13(REGISTER_SCANLINE_STATE)
|
||||
stb r9, 0x17(REGISTER_SCANLINE_STATE)
|
||||
rlwinm r10, r9, 0x1d, 0x1a, 0x1a
|
||||
lbz r9, 0x17a9(state_temp)
|
||||
lbz r9, state_temp->_17A9
|
||||
rlwinm r9, r9, 0x1, 0x0, 0x1e
|
||||
and r9, r9, r8
|
||||
stb r9, 0x10(r26)
|
||||
stb r9, 0x14(r26)
|
||||
stb r9, 0x10(REGISTER_SCANLINE_STATE)
|
||||
stb r9, 0x14(REGISTER_SCANLINE_STATE)
|
||||
addi r9, r9, 0x1
|
||||
stb r9, 0x11(r26)
|
||||
stb r9, 0x15(r26)
|
||||
stb r9, 0x11(REGISTER_SCANLINE_STATE)
|
||||
stb r9, 0x15(REGISTER_SCANLINE_STATE)
|
||||
rlwimi r10, r8, 0x1f, 0x18, 0x18
|
||||
rlwinm r9, r10, 0x1f, 0x1, 0x1f
|
||||
or r10, r10, r9
|
||||
@@ -3663,18 +3669,18 @@ LAB_8003b054:
|
||||
LAB_8003b0b0:
|
||||
lbz r10, state_temp->mapper_chr_bank_ext[11]
|
||||
and r9, r9, r8
|
||||
stb r9, 0x13(r26)
|
||||
lbz r9, 0x17aa(state_temp)
|
||||
stb r9, 0x13(REGISTER_SCANLINE_STATE)
|
||||
lbz r9, state_temp->_17AA
|
||||
and r9, r9, r8
|
||||
stb r9, 0x12(r26)
|
||||
lbz r9, 0x17a9(state_temp)
|
||||
stb r9, 0x12(REGISTER_SCANLINE_STATE)
|
||||
lbz r9, state_temp->_17A9
|
||||
and r9, r9, r8
|
||||
stb r9, 0x11(r26)
|
||||
lbz r9, 0x17a8(state_temp)
|
||||
stb r9, 0x11(REGISTER_SCANLINE_STATE)
|
||||
lbz r9, state_temp->_17A8
|
||||
and r9, r9, r8
|
||||
stb r9, 0x10(r26)
|
||||
lwz r9, 0x10(r26)
|
||||
stw r9, 0x14(r26)
|
||||
stb r9, 0x10(REGISTER_SCANLINE_STATE)
|
||||
lwz r9, (ksNesPPUScanlineState.chr_bank_bg[0])(REGISTER_SCANLINE_STATE)
|
||||
stw r9, (ksNesPPUScanlineState.chr_bank_bg[1])(REGISTER_SCANLINE_STATE)
|
||||
lbz r9, state_temp->mapper_chr_bank_ext[10]
|
||||
subi r10, r10, 0x1
|
||||
lbz r8, state_temp->mapper_chr_bank_ext[9]
|
||||
@@ -3695,9 +3701,9 @@ LAB_8003b0b0:
|
||||
or r10, r10, r0
|
||||
b LAB_8003b138
|
||||
LAB_8003b134:
|
||||
lbz r10, 0x1e(r26)
|
||||
lbz r10, (ksNesPPUScanlineState.chr_bank_ext_upper_sprite)(REGISTER_SCANLINE_STATE)
|
||||
LAB_8003b138:
|
||||
stb r10, 0x1f(r26)
|
||||
stb r10, (ksNesPPUScanlineState.chr_bank_ext_upper_bg)(REGISTER_SCANLINE_STATE)
|
||||
lhz r7, state_temp->ppu_vram_addr_v_hi
|
||||
addi r0, state_temp, state_temp->ppu_nametable_pointers
|
||||
xori r9, r7, 0x100
|
||||
@@ -3720,9 +3726,9 @@ LAB_8003b174:
|
||||
bne LAB_8003b188
|
||||
ori r10, r10, 0x20
|
||||
LAB_8003b188:
|
||||
stb r10, 0x1d(r26)
|
||||
stw r8, 0x0(r26)
|
||||
stw r9, 0x4(r26)
|
||||
stb r10, (ksNesPPUScanlineState.mmc5_ext_mode)(REGISTER_SCANLINE_STATE)
|
||||
stw r8, (ksNesPPUScanlineState.nametable_ptrs[0])(REGISTER_SCANLINE_STATE)
|
||||
stw r9, (ksNesPPUScanlineState.nametable_ptrs[1])(REGISTER_SCANLINE_STATE)
|
||||
andi. r4, r7, 0x7
|
||||
b LAB_8003b1dc
|
||||
LAB_8003b19c:
|
||||
@@ -3733,8 +3739,8 @@ LAB_8003b19c:
|
||||
rlwinm r9, r9, 0x1a, 0x1c, 0x1d
|
||||
lwzx r8, r8, r0
|
||||
lwzx r9, r9, r0
|
||||
stw r8, 0x0(r26)
|
||||
stw r9, 0x4(r26)
|
||||
stw r8, (ksNesPPUScanlineState.nametable_ptrs[0])(REGISTER_SCANLINE_STATE)
|
||||
stw r9, (ksNesPPUScanlineState.nametable_ptrs[1])(REGISTER_SCANLINE_STATE)
|
||||
rlwinm r8, r7, 0x1e, 0x1f, 0x1f
|
||||
rlwinm r9, r7, 0x1, 0x0, 0x1e
|
||||
xor r10, r7, r8
|
||||
@@ -3743,11 +3749,11 @@ LAB_8003b19c:
|
||||
rlwimi r8, r9, 0x0, 0x1d, 0x1d
|
||||
or r4, r8, r10
|
||||
LAB_8003b1dc:
|
||||
stb r7, 0x1c(r26)
|
||||
stb r7, (ksNesPPUScanlineState.vram_addr_y)(REGISTER_SCANLINE_STATE)
|
||||
add r4, state_temp, r4
|
||||
addi r8, r7, 0x1
|
||||
andi. r0, r7, 0x300
|
||||
lbz r10, 0x174c(r4)
|
||||
lbz r10, (ksNesStateObj.ppu_render_latches)(r4)
|
||||
andi. r8, r8, 0xff
|
||||
cmpwi r8, 0xf0
|
||||
lbz r9, state_temp->ppu_fine_x_scroll
|
||||
@@ -3755,22 +3761,22 @@ LAB_8003b1dc:
|
||||
xori r0, r0, 0x200
|
||||
li r8, 0x0
|
||||
LAB_8003b208:
|
||||
sth r9, 0x1a(r26)
|
||||
sth r9, (ksNesPPUScanlineState.fine_x_and_next)(REGISTER_SCANLINE_STATE)
|
||||
or r8, r8, r0
|
||||
sth r8, state_temp->ppu_vram_addr_v_hi
|
||||
subic. r10, r10, 0x80
|
||||
lbz r9, 0x175c(r4)
|
||||
lbz r9, (ksNesStateObj.ppu_render_latches + 0x10)(r4)
|
||||
beq LAB_8003b230
|
||||
stb r10, 0x174c(r4)
|
||||
stb r3, 0x1754(r4)
|
||||
stb r3, 0x175c(r4)
|
||||
stb r10, (ksNesStateObj.ppu_render_latches)(r4)
|
||||
stb r3, (ksNesStateObj.ppu_render_latches + 0x08)(r4)
|
||||
stb r3, (ksNesStateObj.ppu_render_latches + 0x10)(r4)
|
||||
b LAB_8003b244
|
||||
LAB_8003b230:
|
||||
subf r8, r9, r3
|
||||
stb r3, 0x175c(r4)
|
||||
stb r3, (ksNesStateObj.ppu_render_latches + 0x10)(r4)
|
||||
rlwinm r8, r8, 0x5, 0x0, 0x1a
|
||||
subf r8, r8, r26
|
||||
stb r3, 0x1a(r8)
|
||||
subf r8, r8, REGISTER_SCANLINE_STATE
|
||||
stb r3, (ksNesPPUScanlineState.fine_x_and_next)(r8)
|
||||
LAB_8003b244:
|
||||
lbz r8, 0x1020(state_temp)
|
||||
lbz r10, state_temp->sprite0_hit_scanline
|
||||
@@ -3978,7 +3984,7 @@ LAB_8003b4fc:
|
||||
li r9, 0x0
|
||||
stswi r8, r7, 0x8
|
||||
lbz r8, state_temp->mapper
|
||||
cmpwi r8, 0x5
|
||||
cmpwi r8, KS_NES_MAPPER_MMC5
|
||||
bne LAB_8003b54c
|
||||
li r7, 0x40
|
||||
stb r7, state_temp->mmc5_scanline_irq_status
|
||||
@@ -5115,7 +5121,7 @@ entry ksNesStore2006
|
||||
rlwinm r7, r8, 30, 22, 28
|
||||
rlwimi r7, r8, 20, 30, 31
|
||||
lbz r9, state_temp->mapper
|
||||
cmpwi r9, 0x5
|
||||
cmpwi r9, KS_NES_MAPPER_MMC5
|
||||
bne L_8003C0D4
|
||||
andi. r7, r7, 0x7ffe
|
||||
L_8003C0D4:
|
||||
@@ -5163,7 +5169,7 @@ L_8003C130:
|
||||
lbz r7, state_temp->mapper
|
||||
clrrwi r9, r9, 4
|
||||
add r4, r8, r9
|
||||
cmpwi r7, 0x5
|
||||
cmpwi r7, KS_NES_MAPPER_MMC5
|
||||
beq L_8003C180
|
||||
bl ksNesConvertChrToI8
|
||||
b L_8003C184
|
||||
|
||||
+267
-246
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user