Skip to content

Commit cd7cdb6

Browse files
authored
Merge 2a1390d into d4f2d5f
2 parents d4f2d5f + 2a1390d commit cd7cdb6

35 files changed

+15795
-1
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ set(NES_COMPONENTS "nes")
1616
set(GBC_COMPONENTS "gbc")
1717

1818
### SMS ###
19-
# set(SMS_COMPONENTS "sms")
19+
set(SMS_COMPONENTS "sms")
2020

2121
### SNES ###
2222
# set(SNES_COMPONENTS "snes")

components/sms/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
idf_component_register(
2+
INCLUDE_DIRS "include"
3+
SRC_DIRS "src" "teensysms"
4+
PRIV_INCLUDE_DIRS "teensysms"
5+
REQUIRES box-emu-hal
6+
)
7+
# target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-char-subscripts -Wno-attributes -Wno-implicit-fallthrough -Wno-unused-function -Wno-unused-variable -Wno-discarded-qualifiers)
8+
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-pointer-arith -Wno-int-conversion -Wno-parentheses)

components/sms/include/sms.hpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include <string_view>
5+
#include <vector>
6+
7+
void reset_sms();
8+
void init_sms(uint8_t *romdata, size_t rom_data_size);
9+
void init_gg(uint8_t *romdata, size_t rom_data_size);
10+
void load_sms(std::string_view save_path);
11+
void save_sms(std::string_view save_path);
12+
void start_sms_tasks();
13+
void stop_sms_tasks();
14+
void run_sms_rom();
15+
void deinit_sms();
16+
void set_sms_video_original();
17+
void set_sms_video_fit();
18+
void set_sms_video_fill();
19+
std::vector<uint8_t> get_sms_video_buffer();
20+
21+
extern "C" {
22+
void sms_pause_video_task();
23+
void sms_resume_video_task();
24+
void sms_pause_audio_task();
25+
void sms_resume_audio_task();
26+
}

components/sms/src/sms.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include "sms.hpp"
2+
3+
// include private sms headers
4+
extern "C" {
5+
#include "sms.h"
6+
#include "wrapemu.h"
7+
#include "vdp.h"
8+
}
9+
10+
#include <string>
11+
12+
#include "fs_init.hpp"
13+
#include "format.hpp"
14+
#include "spi_lcd.h"
15+
#include "st7789.hpp"
16+
17+
static const int SMS_SCREEN_WIDTH = 256;
18+
static const int SMS_SCREEN_HEIGHT = 192;
19+
static const int SMS_VISIBLE_HEIGHT = 192;
20+
21+
static std::atomic<bool> scaled = false;
22+
static std::atomic<bool> filled = true;
23+
24+
void set_sms_video_original() {
25+
scaled = false;
26+
filled = false;
27+
}
28+
29+
void set_sms_video_fit() {
30+
scaled = true;
31+
filled = false;
32+
}
33+
34+
void set_sms_video_fill() {
35+
scaled = false;
36+
filled = true;
37+
}
38+
39+
void reset_sms() {
40+
}
41+
42+
void emu_DrawLinePal16(unsigned char * VBuf, int width, int height, int line) {
43+
// TODO: implement
44+
}
45+
46+
void init_sms(uint8_t *romdata, size_t rom_data_size) {
47+
sms_Init();
48+
sms.ram = (uint8_t*)get_vram0();
49+
sms.sram= (uint8_t*)get_vram1();
50+
sms.dummy = get_frame_buffer1();
51+
vdp.vram = get_frame_buffer0();
52+
sms_Start(romdata, rom_data_size);
53+
}
54+
55+
void init_gg(uint8_t *romdata, size_t rom_data_size) {
56+
sms_Init();
57+
sms.ram = (uint8_t*)get_vram0();
58+
sms.sram= (uint8_t*)get_vram1();
59+
sms.dummy = get_frame_buffer1();
60+
vdp.vram = get_frame_buffer0();
61+
gg_Start(romdata, rom_data_size);
62+
}
63+
64+
void run_sms_rom() {
65+
auto start = std::chrono::high_resolution_clock::now();
66+
sms_Step();
67+
// frame rate should be 60 FPS, so 1/60th second is what we want to sleep for
68+
auto delay = std::chrono::duration<float>(1.0f/60.0f);
69+
std::this_thread::sleep_until(start + delay);
70+
}
71+
72+
void load_sms(std::string_view save_path) {
73+
// sms_prep_emulation((char *)save_path.data(), console_sms);
74+
}
75+
76+
void save_sms(std::string_view save_path) {
77+
// save_sram((char *)save_path.data(), console_sms);
78+
}
79+
80+
std::vector<uint8_t> get_sms_video_buffer() {
81+
std::vector<uint8_t> frame(SMS_SCREEN_WIDTH * SMS_VISIBLE_HEIGHT * 2);
82+
// the frame data for the SMS is stored in frame_buffer0 as a 8 bit index into the palette
83+
// we need to convert this to a 16 bit RGB565 value
84+
// uint8_t *frame_buffer0 = get_frame_buffer0();
85+
// uint16_t *palette = nullptr; // get_sms_palette();
86+
// for (int i = 0; i < SMS_SCREEN_WIDTH * SMS_VISIBLE_HEIGHT; i++) {
87+
// uint8_t index = frame_buffer0[i];
88+
// uint16_t color = palette[index];
89+
// frame[i * 2] = color & 0xFF;
90+
// frame[i * 2 + 1] = color >> 8;
91+
// }
92+
return frame;
93+
}
94+
95+
void stop_sms_tasks() {
96+
}
97+
98+
void start_sms_tasks() {
99+
}
100+
101+
void deinit_sms() {
102+
sms_DeInit();
103+
}
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
extern "C" {
2+
#include "emuapi.h"
3+
}
4+
5+
#include "AudioPlaySystem.h"
6+
#include "esp_system.h"
7+
8+
#include "driver/i2s.h"
9+
#include "freertos/queue.h"
10+
#include "string.h"
11+
#define I2S_NUM ((i2s_port_t)0)
12+
13+
volatile uint16_t *Buffer;
14+
volatile uint16_t BufferSize;
15+
16+
17+
static const short square[]={
18+
32767,32767,32767,32767,
19+
32767,32767,32767,32767,
20+
32767,32767,32767,32767,
21+
32767,32767,32767,32767,
22+
32767,32767,32767,32767,
23+
32767,32767,32767,32767,
24+
32767,32767,32767,32767,
25+
32767,32767,32767,32767,
26+
-32767,-32767,-32767,-32767,
27+
-32767,-32767,-32767,-32767,
28+
-32767,-32767,-32767,-32767,
29+
-32767,-32767,-32767,-32767,
30+
-32767,-32767,-32767,-32767,
31+
-32767,-32767,-32767,-32767,
32+
-32767,-32767,-32767,-32767,
33+
-32767,-32767,-32767,-32767,
34+
};
35+
36+
const short noise[] {
37+
-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,
38+
-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,32767,-32767,
39+
-32767,-32767,32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,32767,-32767,
40+
-32767,-32767,32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,32767,-32767,-32767,32767,32767,-32767,
41+
-32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,32767,-32767,-32767,32767,32767,-32767,
42+
-32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,32767,-32767,32767,32767,32767,-32767,
43+
32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,32767,-32767,32767,32767,32767,-32767,
44+
32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,32767,32767,32767,32767,32767,-32767,
45+
32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,32767,32767,32767,32767,32767,-32767,
46+
32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,-32767,32767,32767,32767,-32767,-32767,
47+
32767,-32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,-32767,32767,32767,32767,32767,32767,-32767,
48+
32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,32767,-32767,32767,32767,32767,-32767,-32767,
49+
32767,32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,-32767,32767,32767,32767,32767,32767,-32767,
50+
32767,-32767,32767,-32767,-32767,32767,32767,-32767,32767,32767,-32767,32767,-32767,32767,-32767,-32767,
51+
32767,32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,-32767,32767,32767,32767,32767,32767,-32767,
52+
32767,-32767,32767,-32767,-32767,32767,32767,32767,32767,32767,-32767,32767,-32767,32767,-32767,-32767,
53+
};
54+
55+
#define NOISEBSIZE 0x100
56+
57+
typedef struct
58+
{
59+
unsigned int spos;
60+
unsigned int sinc;
61+
unsigned int vol;
62+
} Channel;
63+
64+
volatile bool playing = false;
65+
66+
67+
static Channel chan[6] = {
68+
{0,0,0},
69+
{0,0,0},
70+
{0,0,0},
71+
{0,0,0},
72+
{0,0,0},
73+
{0,0,0} };
74+
75+
76+
static void snd_Reset(void)
77+
{
78+
chan[0].vol = 0;
79+
chan[1].vol = 0;
80+
chan[2].vol = 0;
81+
chan[3].vol = 0;
82+
chan[4].vol = 0;
83+
chan[5].vol = 0;
84+
chan[0].sinc = 0;
85+
chan[1].sinc = 0;
86+
chan[2].sinc = 0;
87+
chan[3].sinc = 0;
88+
chan[4].sinc = 0;
89+
chan[5].sinc = 0;
90+
}
91+
92+
#ifdef CUSTOM_SND
93+
extern "C" {
94+
void SND_Process(void *sndbuffer, int sndn);
95+
}
96+
#endif
97+
98+
99+
static void snd_Mixer16(uint16_t * stream, int len )
100+
{
101+
if (playing)
102+
{
103+
#ifdef CUSTOM_SND
104+
SND_Process((void*)stream, len);
105+
#else
106+
int i;
107+
long s;
108+
//len = len >> 1;
109+
110+
short v0=chan[0].vol;
111+
short v1=chan[1].vol;
112+
short v2=chan[2].vol;
113+
short v3=chan[3].vol;
114+
short v4=chan[4].vol;
115+
short v5=chan[5].vol;
116+
for (i=0;i<len;i++)
117+
{
118+
s = ( v0*(square[(chan[0].spos>>8)&0x3f]) );
119+
s+= ( v1*(square[(chan[1].spos>>8)&0x3f]) );
120+
s+= ( v2*(square[(chan[2].spos>>8)&0x3f]) );
121+
s+= ( v3*(noise[(chan[3].spos>>8)&(NOISEBSIZE-1)]) );
122+
s+= ( v4*(noise[(chan[4].spos>>8)&(NOISEBSIZE-1)]) );
123+
s+= ( v5*(noise[(chan[5].spos>>8)&(NOISEBSIZE-1)]) );
124+
*stream++ = int16_t((s>>11));
125+
chan[0].spos += chan[0].sinc;
126+
chan[1].spos += chan[1].sinc;
127+
chan[2].spos += chan[2].sinc;
128+
chan[3].spos += chan[3].sinc;
129+
chan[4].spos += chan[4].sinc;
130+
chan[5].spos += chan[5].sinc;
131+
}
132+
#endif
133+
}
134+
}
135+
136+
void AudioPlaySystem::begin(void)
137+
{
138+
}
139+
140+
void AudioPlaySystem::start(void)
141+
{
142+
playing = true;
143+
}
144+
145+
void AudioPlaySystem::setSampleParameters(float clockfreq, float samplerate) {
146+
}
147+
148+
void AudioPlaySystem::reset(void)
149+
{
150+
snd_Reset();
151+
}
152+
153+
void AudioPlaySystem::stop(void)
154+
{
155+
playing = false;
156+
}
157+
158+
bool AudioPlaySystem::isPlaying(void)
159+
{
160+
return playing;
161+
}
162+
163+
164+
void AudioPlaySystem::sound(int C, int F, int V) {
165+
if (C < 6) {
166+
//printf("play %d %d %d\n",C,F,V);
167+
168+
chan[C].vol = V;
169+
chan[C].sinc = F>>1;
170+
}
171+
}
172+
173+
void AudioPlaySystem::step(void)
174+
{
175+
if (playing) {
176+
int left=DEFAULT_SAMPLERATE/50;
177+
178+
while(left) {
179+
int n=DEFAULT_SAMPLESIZE;
180+
if (n>left) n=left;
181+
snd_Mixer16((uint16_t*)Buffer, n);
182+
//16 bit mono -> 16 bit r+l
183+
for (int i=n-1; i>=0; i--) {
184+
Buffer[i*2+1]=Buffer[i]+32767;
185+
Buffer[i*2]=Buffer[i]+32767;
186+
}
187+
// TODO: update this to use hal
188+
// i2s_write_bytes(I2S_NUM, (const void*)Buffer, n*4, portMAX_DELAY);
189+
left-=n;
190+
}
191+
}
192+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifndef audioplaysystem_h_
2+
#define audioplaysystem_h_
3+
4+
#define DEFAULT_SAMPLESIZE 512 // 22050/50=443 samples per 20ms
5+
#define DEFAULT_SAMPLERATE 22050
6+
7+
class AudioPlaySystem
8+
{
9+
public:
10+
AudioPlaySystem(void) { begin(); }
11+
void begin(void);
12+
void setSampleParameters(float clockfreq, float samplerate);
13+
void reset(void);
14+
void start(void);
15+
void stop(void);
16+
bool isPlaying(void);
17+
void sound(int C, int F, int V);
18+
void buzz(int size, int val);
19+
void step(void);
20+
};
21+
22+
23+
#endif

0 commit comments

Comments
 (0)