Skip to content

Commit 10efef5

Browse files
committed
Improve ks_nes_draw funcs scores some, a bunch of documentation and improvements in ks_nes_core.
1 parent 4b490c1 commit 10efef5

4 files changed

Lines changed: 351 additions & 292 deletions

File tree

include/Famicom/ks_nes_common.h

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ extern "C" {
1313
#define KS_NES_WIDTH 256
1414
#define KS_NES_HEIGHT 228
1515

16+
#define KS_NES_PPU_CYCLES_PER_SCANLINE 341
17+
#define KS_NES_CPU_CYCLES_PER_SCANLINE 114
1618

1719
#define KS_NES_SCANLINE_COUNT 240 // 228 visible + 8 pre-render + 8 post-render
1820
#define KS_NES_SCANLINE_SPRITE_OVERDRAW_COUNT (KS_NES_SCANLINE_COUNT + 32) // 272
@@ -123,6 +125,32 @@ extern "C" {
123125
#define KS_NES_MAPPER_KONAMI_VRC6A 24
124126
#define KS_NES_MAPPER_KONAMI_VRC6B 26
125127

128+
// Memory mapped register addresses
129+
130+
// APU Registers & Flags
131+
#define KS_NES_REG_APU_STATUS 0x4015
132+
#define KS_NES_REG_APU_STATUS_FLG_PULSE1_ENABLE (1 << 0)
133+
#define KS_NES_REG_APU_STATUS_FLG_PULSE2_ENABLE (1 << 1)
134+
#define KS_NES_REG_APU_STATUS_FLG_TRIANGLE_ENABLE (1 << 2)
135+
#define KS_NES_REG_APU_STATUS_FLG_NOISE_ENABLE (1 << 3)
136+
#define KS_NES_REG_APU_STATUS_FLG_DMC_ENABLE (1 << 4)
137+
138+
// MMC5 Audio Registers & Flags
139+
#define KS_NES_REG_MMC5_AUDIO_PULSE1_TIMER 0x5000
140+
#define KS_NES_REG_MMC5_AUDIO_PULSE1_LENGTH_CTR 0x5001
141+
#define KS_NES_REG_MMC5_AUDIO_PULSE1_ENVELOPE 0x5002
142+
#define KS_NES_REG_MMC5_AUDIO_PULSE1_SWEEP 0x5003
143+
#define KS_NES_REG_MMC5_AUDIO_PULSE2_TIMER 0x5004
144+
#define KS_NES_REG_MMC5_AUDIO_PULSE2_LENGTH_CTR 0x5005
145+
#define KS_NES_REG_MMC5_AUDIO_PULSE2_ENVELOPE 0x5006
146+
#define KS_NES_REG_MMC5_AUDIO_PULSE2_SWEEP 0x5007
147+
#define KS_NES_REG_MMC5_AUDIO_PCM_MODE_IRQ 0x5010 // bit0 = mode select, 0 = write, 1 = read & bit7 = PCM IRQ enable
148+
#define KS_NES_REG_MMC5_AUDIO_RAW_PCM 0x5011
149+
#define KS_NES_REG_MMC5_AUDIO_STATUS 0x5015 // only bottom two bits are used (bit0/1) and toggle pulse1/2
150+
#define KS_NES_REG_MMC5_AUDIO_STATUS_PULSE1 (1 << 0)
151+
#define KS_NES_REG_MMC5_AUDIO_STATUS_PULSE2 (1 << 1)
152+
#define KS_NES_REG_MMC5_AUDIO_STATUS_PULSE_MASK (KS_NES_REG_MMC5_AUDIO_STATUS_PULSE1 | KS_NES_REG_MMC5_AUDIO_STATUS_PULSE2)
153+
126154
// Emulator flags
127155
#define KS_NES_FLAG_NINES_OVER_MODE (1 << 13) // 0x2000, enables "nines over" mode which allows drawing more than 8 sprites per scanline
128156

@@ -160,10 +188,17 @@ typedef struct ksNesOAMEntry {
160188
u8 x_pos;
161189
} ksNesOAMEntry;
162190

191+
// I suspect this struct is fake but it makes readability easier and matches.
192+
typedef struct ksNesScanlineYCoords {
193+
u8 top;
194+
u8 bottom;
195+
} ksNesScanlineYCoords;
196+
163197
typedef struct ksNesDrawCtx {
164198
/* 0x0000 */ union {
165199
u8 sprite_scanline_limit[KS_NES_SCANLINE_SPRITE_OVERDRAW_COUNT]; // tracks the number of sprites that have been drawn on each scanline
166200
u8 scanline_y_coords[2 * 256]; // tracks the Y coordinate of the top & bottom of each scanline
201+
u8 scanline_raw_buf[512]; // raw buffer (most likely definition?)
167202
};
168203

169204
/* 0x0200 */ u8 mmc2_scanline_latch_tiles[KS_NES_SCANLINE_COUNT + 16]; // tracks which tiles should be accessible on each scanline based on MMC2 latch settings
@@ -179,23 +214,25 @@ typedef struct ksNesDrawCtx {
179214
/* 0x8EE8 */ Mtx34 draw_mtx;
180215
} ksNesDrawCtx;
181216

217+
#define KS_NES_TYPE_FROM_DRAW_CTX_SCANLINE_BUF_OFS(type, draw_ctx, ofs) ((type*)((((u8*)(draw_ctx).scanline_raw_buf) + (ofs))))
218+
#define KS_NES_TYPE_FROM_DRAW_CTX_SCANLINE_BUF(type, draw_ctx, idx) ((type*)(((u8*)(draw_ctx).scanline_raw_buf) + ((idx) * sizeof(type))))
219+
182220
typedef struct ksNesCommonWorkObj {
183221
/* 0x0000 */ u8* nesromp;
184222
/* 0x0004 */ u8* noise_bufp;
185223
/* 0x0008 */ size_t chr_to_i8_buf_size;
186224
/* 0x000C */ u8* chr_to_u8_bufp;
187225
/* 0x0010 */ u8* result_bufp;
188-
/* 0x0014 */ int _0014;
189-
/* 0x0018 */ int _0018;
226+
/* 0x0014 */ u32 cpu_cycle_count;
227+
/* 0x0018 */ u32 total_cpu_cycles;
190228
/* 0x001C */ u8 frames;
191-
/* 0x001D */ u8 _001D;
229+
/* 0x001D */ u8 fds_disk_count;
192230
/* 0x001E */ u8 _001E;
193231
/* 0x001F */ u8 _001F;
194-
/* 0x0020 */ u32 pads[4];
195-
/* 0x0030 */ u32 _0030;
196-
/* 0x0034 */ u32 _0034;
197-
/* 0x0038 */ u32 _0038;
198-
/* 0x003C */ u8 _003C[0x0048 - 0x003C];
232+
/* 0x0020 */ u32 pads[4+3];
233+
/* 0x003C */ u8 _003C;
234+
/* 0x0040 */ u32 _0040;
235+
/* 0x0044 */ u32 _0044;
199236
/* 0x0048 */ size_t prg_size;
200237
/* 0x004C */ u8 _004C[0x0060 - 0x004C];
201238
/* 0x0060 */ ksNesDrawCtx draw_ctx;
@@ -205,16 +242,16 @@ typedef struct ksNesStateObj {
205242
/* 0x0000 */ u8 wram[KS_NES_WRAM_SIZE];
206243
/* 0x0800 */ u8 ppu_nametable_ram[KS_NES_PPU_NAMETABLE_RAM_SIZE];
207244
/* 0x1000 */ u8 cartridge_nametable_ram[28];
208-
/* 0x101C */ u8 primary_oam[0x100];
209-
/* 0x111C */ u8 _pad[4]; // this might not exist and instead the next member might be ATTRIBUTE_ALIGN(16/32)
245+
/* 0x101C */ u8 _pad[4]; // this might not exist and instead the next member might be ATTRIBUTE_ALIGN(16/32)
246+
/* 0x1020 */ ksNesOAMEntry primary_oam[KS_NES_OAM_TABLE_SIZE]; // u8 primary_oam[0x100];
210247
/* 0x1120 */ u8 mmc5_extension_ram[0x400];
211248
// these are all function pointers.
212249
// leaving these as void pointers until we figure out the function signature.
213250
/* 0x1520 */ void* store_ppu_func[8]; // ksNesStorePPUFuncTblDefault
214-
/* 0x1540 */ void* store_io_func[0x28]; // ksNesStoreIOFuncTblDefault
251+
/* 0x1540 */ void* store_io_func[40]; // ksNesStoreIOFuncTblDefault
215252
/* 0x15E0 */ void* store_func[8]; // ksNesStoreFuncTblDefault
216253
/* 0x1600 */ void* load_func[8]; // ksNesLoadFuncTblDefault
217-
/* 0x1620 */ void* load_io_func[0x18]; // ksNesLoadIOFuncTblDefault
254+
/* 0x1620 */ void* load_io_func[24]; // ksNesLoadIOFuncTblDefault
218255
/* 0x1680 */ u8* cpu_0000_1fff; // work RAM and its mirrors
219256
/* 0x1684 */ u8* cpu_2000_3fff; // PPU registers and their mirrors
220257
/* 0x1688 */ u8* cpu_4000_5fff; // APU registers, I/O registers, and usually unmapped cartridge addresses

src/static/Famicom/famicom.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2119,11 +2119,11 @@ static int famicom_rom_load() {
21192119
u32 flags = 0;
21202120
wp->prg_size = KS_NES_PRGROM_SIZE;
21212121
wp->noise_bufp = famicomCommon.noise_bufp;
2122-
wp->_001D = 4;
2122+
wp->fds_disk_count = 4;
21232123
wp->chr_to_u8_bufp = famicomCommon.chr_to_i8_bufp;
21242124
wp->chr_to_i8_buf_size = CHR_TO_I8_BUF_SIZE;
21252125
wp->result_bufp = famicomCommon.result_bufp;
2126-
wp->_0018 = 0;
2126+
wp->total_cpu_cycles = 0;
21272127

21282128
if (famicomCommon.noise_bufp == nullptr) {
21292129
flags |= 0x40; // no sound?
@@ -2412,9 +2412,9 @@ extern void famicom_1frame() {
24122412
}
24132413

24142414
famicom_key_convert();
2415-
famicomCommon.wp->_0030 = 0;
2416-
famicomCommon.wp->_0034 = 0;
2417-
famicomCommon.wp->_0038 = 0;
2415+
famicomCommon.wp->pads[4] = 0;
2416+
famicomCommon.wp->pads[5] = 0;
2417+
famicomCommon.wp->pads[6] = 0;
24182418

24192419
/* Special input modes activated when L & R are held */
24202420
/*
@@ -2502,7 +2502,7 @@ extern void famicom_1frame() {
25022502
speed_show--;
25032503
}
25042504

2505-
famicomCommon.wp->_0014 = 0;
2505+
famicomCommon.wp->cpu_cycle_count = 0;
25062506
famicomCommon.wp->frames = frames;
25072507

25082508
do {

0 commit comments

Comments
 (0)