Files
player/Project/Src/NES/nes_main.c

448 lines
12 KiB
C
Raw Normal View History

2025-07-10 11:30:57 +08:00
//////////////////////////////////////////////////////////////////////////////////
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ye781205<30><35>NESģ<53><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ALIENTEK STM32F407<30><37><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// NES<45><53><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD>@ALIENTEK
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̳:www.openedv.com
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:2014/7/1
// <20><EFBFBD><E6B1BE>V1.0
//////////////////////////////////////////////////////////////////////////////////
#include "nes_main.h"
#include "dac.h"
2025-06-27 00:32:57 +08:00
#include "main.h"
#include "mymem.h"
2025-07-10 11:30:57 +08:00
#include "nes_apu.h"
#include "nes_mapper.h"
#include "nes_ppu.h"
#include "stm32f4xx.h"
2025-06-27 00:32:57 +08:00
#include "ff.h"
#include "string.h"
2025-07-10 11:30:57 +08:00
uint8_t nes_frame_cnt; // nes֡<73><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int MapperNo; // map<61><70><EFBFBD><EFBFBD>
int NES_scanline; // nesɨ<73><C9A8><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
int VROM_1K_SIZE;
int VROM_8K_SIZE;
2025-07-10 11:30:57 +08:00
uint8_t PADdata; // <20>ֱ<EFBFBD>1<EFBFBD><31>ֵ [7:0]<5D><>7 <20><>6 <20><>5 <20><>4 Start3 Select2 B1 A0
uint8_t PADdata1; // <20>ֱ<EFBFBD>2<EFBFBD><32>ֵ [7:0]<5D><>7 <20><>6 <20><>5 <20><>4 Start3 Select2 B1 A0
uint8_t *NES_RAM; // <20><><EFBFBD><EFBFBD>1024<32>ֽڶ<D6BD><DAB6><EFBFBD>
uint8_t *NES_SRAM;
NES_header *RomHeader; // rom<6F>ļ<EFBFBD>ͷ
MAPPER *NES_Mapper;
MapperCommRes *MAPx;
uint8_t *spr_ram; // <20><><EFBFBD><EFBFBD>RAM,256<35>ֽ<EFBFBD>
ppu_data *ppu; // ppuָ<75><D6B8>
uint8_t *VROM_banks;
uint8_t *VROM_tiles;
apu_t *apu; // apuָ<75><D6B8>
uint16_t *wave_buffers;
uint16_t *i2sbuf1; // <20><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>֡,ռ<><D5BC><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD> 367*4 <20>ֽ<EFBFBD>@22050Hz
uint16_t *i2sbuf2; // <20><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>֡,ռ<><D5BC><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD> 367*4 <20>ֽ<EFBFBD>@22050Hz
uint8_t *romfile; // nes<65>ļ<EFBFBD>ָ<EFBFBD><D6B8><><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>nes<65>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ַ.
2025-06-27 00:32:57 +08:00
//////////////////////////////////////////////////////////////////////////////////////
2025-07-10 11:30:57 +08:00
// <20><>¼nes<65>Ƿ<EFBFBD><C7B7><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>
static uint8_t g_nes_break = 0;
// <20><><EFBFBD><EFBFBD>ROM
// <20><><EFBFBD><EFBFBD>ֵ:0,<2C>ɹ<EFBFBD>
// 1,<2C>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>
// 3,map<61><70><EFBFBD><EFBFBD>
uint8_t nes_load_rom(void) {
uint8_t *p;
uint8_t i;
uint8_t res = 0;
p = (uint8_t *)romfile;
if (strncmp((char *)p, "NES", 3) == 0) {
RomHeader->ctrl_z = p[3];
RomHeader->num_16k_rom_banks = p[4];
RomHeader->num_8k_vrom_banks = p[5];
RomHeader->flags_1 = p[6];
RomHeader->flags_2 = p[7];
if (RomHeader->flags_1 & 0x04)
p += 512; // <20><>512<31>ֽڵ<D6BD>trainer:
if (RomHeader->num_8k_vrom_banks > 0) // <20><><EFBFBD><EFBFBD>VROM,<2C><><EFBFBD><EFBFBD>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD>
{
VROM_banks = p + 16 + (RomHeader->num_16k_rom_banks * 0x4000);
#if NES_RAM_SPEED == 1 // 1:<3A>ڴ<EFBFBD>ռ<EFBFBD><D5BC>С 0:<3A>ٶȿ<D9B6>
VROM_tiles = VROM_banks;
#else
VROM_tiles = mymalloc(RomHeader->num_8k_vrom_banks * 8 *
1024); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1MB<4D>ڴ<EFBFBD>!!!
if (VROM_tiles == 0)
VROM_tiles =
VROM_banks; // <20>ڴ治<DAB4><E6B2BB><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>VROM_titles<65><73>VROM_banks<6B><73><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
compile(RomHeader->num_8k_vrom_banks * 8 * 1024 / 16, VROM_banks,
VROM_tiles);
#endif
} else {
VROM_banks = mymalloc(8 * 1024);
VROM_tiles = mymalloc(8 * 1024);
if (!VROM_banks || !VROM_tiles)
res = 1;
}
VROM_1K_SIZE = RomHeader->num_8k_vrom_banks * 8;
VROM_8K_SIZE = RomHeader->num_8k_vrom_banks;
MapperNo = (RomHeader->flags_1 >> 4) | (RomHeader->flags_2 & 0xf0);
if (RomHeader->flags_2 & 0x0E)
MapperNo = RomHeader->flags_1 >> 4; // <20><><EFBFBD>Ը<EFBFBD><D4B8><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// printf("use map:%d\r\n",MapperNo);
for (i = 0; i < 255; i++) // <20><><EFBFBD><EFBFBD>֧<EFBFBD>ֵ<EFBFBD>Mapper<65><72>
{
if (MapTab[i] == MapperNo)
break;
if (MapTab[i] == -1)
res = 3;
}
if (res == 0) {
switch (MapperNo) {
case 1:
MAP1 = mymalloc(sizeof(Mapper1Res));
if (!MAP1)
res = 1;
break;
case 4:
case 6:
case 16:
case 17:
case 18:
case 19:
case 21:
case 23:
case 24:
case 25:
case 64:
case 65:
case 67:
case 69:
case 85:
case 189:
MAPx = mymalloc(sizeof(MapperCommRes));
if (!MAPx)
res = 1;
break;
default:
break;
}
}
}
return res; // <20><><EFBFBD><EFBFBD>ִ<EFBFBD>н<EFBFBD><D0BD><EFBFBD>
}
// <20><><EFBFBD><EFBFBD>NES_RAM<41><4D><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>ʱ<EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD>ָ<EFBFBD><D6B8>
2025-06-27 00:32:57 +08:00
void *nes_ram_alignment;
2025-07-10 11:30:57 +08:00
// <20>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
void nes_sram_free(void) {
// myfree(NES_RAM);
myfree(nes_ram_alignment);
myfree(NES_SRAM);
myfree(RomHeader);
myfree(NES_Mapper);
myfree(spr_ram);
myfree(ppu);
myfree(apu);
myfree(wave_buffers);
myfree(i2sbuf1);
myfree(i2sbuf2);
myfree(romfile);
if ((VROM_tiles != VROM_banks) && VROM_banks &&
VROM_tiles) // <20><><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>ΪVROM_banks<6B><73>VROM_tiles<65><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>,<2C><><EFBFBD>ͷ<EFBFBD>
{
myfree(VROM_banks);
myfree(VROM_tiles);
}
switch (MapperNo) // <20>ͷ<EFBFBD>map<61>ڴ<EFBFBD>
{
case 1: // <20>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
myfree(MAP1);
break;
case 4:
case 6:
case 16:
case 17:
case 18:
case 19:
case 21:
case 23:
case 24:
case 25:
case 64:
case 65:
case 67:
case 69:
case 85:
case 189:
myfree(MAPx);
break; // <20>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
default:
break;
}
NES_RAM = 0;
NES_SRAM = 0;
RomHeader = 0;
NES_Mapper = 0;
spr_ram = 0;
ppu = 0;
apu = 0;
wave_buffers = 0;
i2sbuf1 = 0;
i2sbuf2 = 0;
romfile = 0;
VROM_banks = 0;
VROM_tiles = 0;
MAP1 = 0;
MAPx = 0;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// ΪNES<45><53><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
// romsize:nes<65>ļ<EFBFBD><C4BC><EFBFBD>С
// <20><><EFBFBD><EFBFBD>ֵ:0,<2C><><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>
// 1,<2C><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
uint8_t nes_sram_malloc(uint32_t romsize) {
uint16_t i = 0;
// NES_RAM<41><4D>Ҫ0x800<30><30>С<EFBFBD><D0A1><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0x400<30><30><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD><EFBFBD>1024<32>ֽڶ<D6BD><DAB6><EFBFBD>
nes_ram_alignment = mymalloc(0x800 + 0x400);
NES_RAM = (void *)(((uint32_t)nes_ram_alignment + 0x400) & 0xfffffc00);
NES_SRAM = mymalloc(0X2000);
RomHeader = mymalloc(sizeof(NES_header));
NES_Mapper = mymalloc(sizeof(MAPPER));
spr_ram = mymalloc(0X100);
ppu = mymalloc(sizeof(ppu_data));
apu = mymalloc(sizeof(apu_t)); // sizeof(apu_t)= 12588
wave_buffers = mymalloc(APU_PCMBUF_SIZE * 2);
i2sbuf1 = mymalloc(APU_PCMBUF_SIZE * 4 + 10);
i2sbuf2 = mymalloc(APU_PCMBUF_SIZE * 4 + 10);
romfile = mymalloc(romsize); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸrom<6F>ռ<EFBFBD>,<2C><><EFBFBD><EFBFBD>nes<65>ļ<EFBFBD><C4BC><EFBFBD>С
if (i == 64 || !NES_RAM || !NES_SRAM || !RomHeader || !NES_Mapper ||
!spr_ram || !ppu || !apu || !wave_buffers || !i2sbuf1 || !i2sbuf2 ||
!romfile) {
nes_sram_free();
return 1;
}
memset(NES_SRAM, 0, 0X2000); // <20><><EFBFBD><EFBFBD>
memset(RomHeader, 0, sizeof(NES_header)); // <20><><EFBFBD><EFBFBD>
memset(NES_Mapper, 0, sizeof(MAPPER)); // <20><><EFBFBD><EFBFBD>
memset(spr_ram, 0, 0X100); // <20><><EFBFBD><EFBFBD>
memset(ppu, 0, sizeof(ppu_data)); // <20><><EFBFBD><EFBFBD>
memset(apu, 0, sizeof(apu_t)); // <20><><EFBFBD><EFBFBD>
memset(wave_buffers, 0, APU_PCMBUF_SIZE * 2); // <20><><EFBFBD><EFBFBD>
memset(i2sbuf1, 0, APU_PCMBUF_SIZE * 4 + 10); // <20><><EFBFBD><EFBFBD>
memset(i2sbuf2, 0, APU_PCMBUF_SIZE * 4 + 10); // <20><><EFBFBD><EFBFBD>
memset(romfile, 0, romsize); // <20><><EFBFBD><EFBFBD>
return 0;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
int nes_xoff = 0; // <20><>ʾ<EFBFBD><CABE>x<EFBFBD><EFBFBD><E1B7BD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD><><CAB5><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>=256-2*nes_xoff)
int nes_yoff = 0;
// <20><>ʼnes<65><73>Ϸ
// pname:nes<65><73>Ϸ·<CFB7><C2B7>
// <20><><EFBFBD><EFBFBD>ֵ:
// 0,<2C><><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD>
// 1,<2C>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>
// 2,<2C>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
// 3,<2C><>֧<EFBFBD>ֵ<EFBFBD>map
uint8_t nes_load(uint8_t *pname, void *lcd_addr, int x, int y) {
nes_xoff = x;
nes_yoff = y;
FIL *file;
FILINFO *file_info;
UINT br;
uint8_t res = 0;
g_nes_break = 0;
file = mymalloc(sizeof(FIL));
file_info = mymalloc(sizeof(FILINFO));
if (file == 0)
return 1; // <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>.
res = f_stat((char *)pname, file_info);
if (res != FR_OK) // <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ʧ<EFBFBD><CAA7>
{
myfree(file);
myfree(file_info);
return 2;
}
res = nes_sram_malloc(file_info->fsize); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
if (res == 0) {
f_open(file, (char *)pname, FA_READ);
f_read(file, romfile, file_info->fsize, &br); // <20><>ȡnes<65>ļ<EFBFBD>
res = nes_load_rom(); // <20><><EFBFBD><EFBFBD>ROM
if (res == 0) {
Mapper_Init(); // map<61><70>ʼ<EFBFBD><CABC>
cpu6502_init(); // <20><>ʼ<EFBFBD><CABC>6502,<2C><><EFBFBD><EFBFBD>λ
PPU_reset(lcd_addr); // ppu<70><75>λ
apu_init(); // apu<70><75>ʼ<EFBFBD><CABC>
nes_sound_open(0, APU_SAMPLE_RATE); // <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
nes_emulate_frame(); // <20><><EFBFBD><EFBFBD>NESģ<53><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD>
nes_sound_close(); // <20>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
}
f_close(file);
myfree(file); // <20>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
myfree(file_info);
nes_sram_free(); // <20>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
return res;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4>е<EFBFBD><D0B5><EFBFBD>Ϸ
uint8_t nes_start(uint8_t *file, int fileSize, void *lcd_addr, int x, int y) {
nes_xoff = x;
nes_yoff = y;
uint8_t res = 0;
g_nes_break = 0;
res = nes_sram_malloc(fileSize); // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
if (res == 0) {
mymemcpy(romfile, file, fileSize); // <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>пռ<D0BF>
res = nes_load_rom(); // <20><><EFBFBD><EFBFBD>ROM
if (res == 0) {
Mapper_Init(); // map<61><70>ʼ<EFBFBD><CABC>
cpu6502_init(); // <20><>ʼ<EFBFBD><CABC>6502,<2C><><EFBFBD><EFBFBD>λ
PPU_reset(lcd_addr); // ppu<70><75>λ
apu_init(); // apu<70><75>ʼ<EFBFBD><CABC>
nes_sound_open(0, APU_SAMPLE_RATE); // <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
nes_emulate_frame(); // <20><><EFBFBD><EFBFBD>NESģ<53><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD>
nes_sound_close(); // <20>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
}
nes_sram_free(); // <20>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
return res;
}
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>
void nes_set_window(void) {}
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
// <20><>ȡ<EFBFBD><C8A1>Ϸ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD>
void nes_get_gamepadval(void) {
#include "usart.h"
PADdata = USART3_GetKey();
PADdata1 = 0;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// nesģ<73><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD>
void nes_emulate_frame(void) {
uint8_t nes_frame;
// TIM3_Int_Init(10000-1,8400-1);//<2F><><EFBFBD><EFBFBD>TIM3 ,1s<31>ж<EFBFBD>һ<EFBFBD><D2BB>
nes_set_window(); // <20><><EFBFBD>ô<EFBFBD><C3B4><EFBFBD>
while (1) {
// LINES 0-239
PPU_start_frame();
// LCD_SwitchLayerBuff();//<2F>л<EFBFBD>֡
for (NES_scanline = 0; NES_scanline < 240; NES_scanline++) {
run6502(113 * 256);
NES_Mapper->HSync(NES_scanline);
// ɨ<><C9A8>һ<EFBFBD><D2BB>
if (nes_frame == 0)
scanline_draw(NES_scanline);
else
do_scanline_and_dont_draw(NES_scanline);
}
// LCD_ExitLayerBuff ();
NES_scanline = 240;
run6502(113 * 256); // <20><><EFBFBD><EFBFBD>1<EFBFBD><31>
NES_Mapper->HSync(NES_scanline);
start_vblank();
if (NMI_enabled()) {
cpunmi = 1;
run6502(7 * 256); // <20><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
}
NES_Mapper->VSync();
// LINES 242-261
for (NES_scanline = 241; NES_scanline < 262; NES_scanline++) {
run6502(113 * 256);
NES_Mapper->HSync(NES_scanline);
}
end_vblank();
nes_get_gamepadval(); // ÿ3֡<33><D6A1>ѯһ<D1AF><D2BB>USB
apu_soundoutput(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD>
nes_frame_cnt++;
nes_frame++;
if (nes_frame > NES_SKIP_FRAME)
nes_frame = 0; // <20><>֡
uint8_t nesBreak(void);
if (nesBreak())
break;
if (Touch_GetState()->x[1] != 0)
break;
}
// TIM3->CR1&=~(1<<0);//<2F>رն<D8B1>ʱ<EFBFBD><CAB1>3
}
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
uint8_t nesBreak(void) {
uint8_t t = 0;
if ((PADdata & 0x0c) == 0x0c) {
g_nes_break = 0x0c;
}
if ((g_nes_break) && (t = USART3_GetKeyPressed(), t & 0x0c)) {
g_nes_break &= ~t;
if (g_nes_break == 0)
return 1;
}
return 0;
}
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
// <20><>6502.s<><73><EFBFBD><EFBFBD><E6B1BB><EFBFBD><EFBFBD>
void debug_6502(uint16_t reg0, uint8_t reg1) {
// printf("6502 error:%x,%d\r\n",reg0,reg1);
}
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
//////////////////////////////////////////////////////////////////////////////////
// nes,<2C><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>֧<EFBFBD>ֲ<EFBFBD><D6B2><EFBFBD>
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
static vu8 g_buff_Invalid = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ЧʱҪ<CAB1><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static vu8 g_buff_useing; // <20><>ǰDMA<4D><41>ʹ<EFBFBD><CAB9><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
static DAC_UserStruct g_dac;
2025-07-10 11:30:57 +08:00
static void dma_tx_callback(DAC_UserStruct *dac) {
uint16_t i;
g_buff_useing = dac->buff_useing;
g_buff_Invalid = 1;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// NES<45><53><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>
int nes_sound_open(int samples_per_sync, int sample_rate) {
// <20><>ʼ<EFBFBD><CABC>DAC
g_dac.buff1 = (uint32_t *)i2sbuf1;
g_dac.buff2 = (uint32_t *)i2sbuf2;
g_dac.buff_size = APU_PCMBUF_SIZE * 4;
g_dac.rate = RATE22050;
g_dac.call_back = dma_tx_callback;
DAC_NormalInit(&g_dac);
return 1;
}
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
// NES<45>ر<EFBFBD><D8B1><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>
void nes_sound_close(void) { DAC_NormalDeInit(&g_dac); }
void nes_apu_fill_buffer(int samples, uint16_t *wavebuf) {
if (DAC_GetDacHander() != &g_dac)
return;
uint16_t i;
uint16_t *p;
while (g_buff_Invalid == 0) // <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
rt_thread_delay(5);
};
if (g_buff_useing == 0) {
p = (uint16_t *)i2sbuf2;
} else {
p = (uint16_t *)i2sbuf1;
}
{
for (i = 0; i < APU_PCMBUF_SIZE; i++) {
p[2 * i] = ((wavebuf[i] + 0x8000) >> 4);
p[2 * i + 1] = p[2 * i];
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>Ч
g_buff_Invalid = 0;
}