@@ -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+
163197typedef 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+
182220typedef 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
0 commit comments