Get sound working; add partial updates (scanlines) to gfx driver

This commit is contained in:
Jeroen Domburg 2017-10-29 12:41:49 +08:00
parent d7e63ad200
commit 36dcd10658
4 changed files with 134 additions and 67 deletions

View File

@ -101,7 +101,7 @@ void adns900_get_dxdybtn(int *x, int *y, int *btn) {
sy|=adnsRead(0x6)<<8; sy|=adnsRead(0x6)<<8;
ets_delay_us(100); ets_delay_us(100);
*btn=gpio_get_level(ADNS_MISO)?0:1; *btn=gpio_get_level(ADNS_MISO)?0:1;
if (sx!=0 || sy!=0) printf("Mouse: %hd %hd %d\n", sx, sy, *btn); // if (sx!=0 || sy!=0) printf("Mouse: %hd %hd %d\n", sx, sy, *btn);
*x=sx; *x=sx;
*y=sy; *y=sy;
} }

View File

@ -62,10 +62,13 @@ static const DispPacket initPackets[]={
}; };
#define DO_RESCALE 1
#if DO_RESCALE
#define SCALE_FACT 51 //Floating-point number, actually x/32. Divide mac reso by this to get lcd reso. #define SCALE_FACT 51 //Floating-point number, actually x/32. Divide mac reso by this to get lcd reso.
#else
#define SCALE_FACT 32
#endif
static uint8_t mask[512]; static uint8_t mask[512];
static void calcLut() { static void calcLut() {
@ -115,7 +118,7 @@ static int IRAM_ATTR findMacVal(uint8_t *data, int x, int y) {
// //
// Due to the weird buildup, a horizontal subpixel actually is 1/3rd real pixel wide! // Due to the weird buildup, a horizontal subpixel actually is 1/3rd real pixel wide!
#if 1 #if DO_RESCALE
static int IRAM_ATTR findPixelVal(uint8_t *data, int x, int y) { static int IRAM_ATTR findPixelVal(uint8_t *data, int x, int y) {
int sx=(x*SCALE_FACT); //32th is 512/320 -> scale 512 mac screen to 320 width int sx=(x*SCALE_FACT); //32th is 512/320 -> scale 512 mac screen to 320 width
@ -177,50 +180,88 @@ static void initLcd() {
printf("Display inited.\n"); printf("Display inited.\n");
} }
static inline void setColRange(int xstart, int xend) {
uint8_t cmd[5];
//No idea why the *2... maybe per byte?
xstart=xstart*2;
xend=xend*2;
cmd[0]=0x2a; //set_col_addr
cmd[1]=(xstart>>8); //scolh
cmd[2]=(xstart&0xff); //scoll
cmd[3]=(xend>>8); //ecolh
cmd[4]=(xend&0xff); //ecoll
mipiDsiSendLong(0x39, cmd, 5);
}
static inline void setRowRange(int ystart, int yend) {
uint8_t cmd[5];
cmd[0]=0x2b; //set_page_addr
cmd[1]=(ystart>>8); //scolh
cmd[2]=(ystart&0xff); //scoll
cmd[3]=(yend>>8); //ecolh
cmd[4]=(yend&0xff); //ecoll
mipiDsiSendLong(0x39, cmd, 5);
}
static void IRAM_ATTR displayTask(void *arg) { static void IRAM_ATTR displayTask(void *arg) {
uint8_t *img=malloc((LINESPERBUF*320*2)+1); uint8_t *img=malloc((LINESPERBUF*320*2)+1);
assert(img); assert(img);
calcLut(); calcLut();
uint8_t cmd[5]; uint8_t cmd[5];
uint8_t *oldImg=malloc(512*342/8);
int firstrun=1; int firstrun=1;
setColRange(0, 319);
while(1) { while(1) {
int l=0; int l=0;
mipiResync(); mipiResync();
xSemaphoreTake(dispSem, portMAX_DELAY); xSemaphoreTake(dispSem, portMAX_DELAY);
#if 0
cmd[0]=0x2a; //set_col_addr
cmd[1]=0; //scolh
cmd[2]=40; //scoll
cmd[3]=(320>>8); //ecolh
cmd[4]=(320&0xff); //ecoll
mipiDsiSendLong(0x39, cmd, 4);
cmd[0]=0x2b; //set_row_addr
cmd[1]=0; //scolh
cmd[2]=40; //scoll
cmd[3]=(320>>8); //ecolh
cmd[4]=(320&0xff); //ecoll
mipiDsiSendLong(0x39, cmd, 4);
#endif
uint8_t *myData=(uint8_t*)currFbPtr; uint8_t *myData=(uint8_t*)currFbPtr;
img[0]=0x2c;
uint8_t *p=&img[1]; int xstart, xend, ystart, yend;
for (int j=0; j<319; j++) { if (!firstrun) {
for (int i=0; i<320; i++) { xstart=0; xend=320;
int v=findPixelVal(myData, i, j); for (ystart=0; ystart<342; ystart++) {
*p++=(v&0xff); if (memcmp(oldImg+64*ystart, myData+64*ystart, 64)!=0) break;
*p++=(v>>8);
} }
l++; for (yend=342-1; yend>=ystart; --yend) {
if (l>=LINESPERBUF || j==319) { if (memcmp(oldImg+64*yend, myData+64*yend, 64)!=0) break;
mipiDsiSendLong(0x39, img, (LINESPERBUF*320*2)+1);
img[0]=0x3c;
l=0;
p=&img[1];
if (!firstrun && j>=200) break; //no need to render black bar in subsequent times
firstrun=0;
} }
if (ystart==342) {
//No need for update
yend=342;
} else {
ystart=(ystart*32)/SCALE_FACT-1;
yend=(yend*32)/SCALE_FACT+1;
if (ystart<0) ystart=0;
printf("Changed %d to %d\n", ystart, yend);
}
} else {
xstart=0; xend=320;
ystart=0; yend=320;
}
memcpy(oldImg, myData, 512*342/8);
if (ystart!=yend) {
setRowRange(ystart, 319);
img[0]=0x2c;
uint8_t *p=&img[1];
for (int j=ystart; j<yend; j++) {
for (int i=0; i<320; i++) {
int v=findPixelVal(myData, i, j);
*p++=(v&0xff);
*p++=(v>>8);
}
l++;
if (l>=LINESPERBUF || j==yend-1) {
mipiDsiSendLong(0x39, img, (l*320*2)+1);
img[0]=0x3c;
l=0;
p=&img[1];
if (!firstrun && j>=200) break; //no need to render black bar in subsequent times
}
}
firstrun=0;
} }
} }
} }

View File

@ -9,28 +9,50 @@
static QueueHandle_t soundQueue; static QueueHandle_t soundQueue;
int sndDone() { //powers of 2 plzthx
return uxQueueSpacesAvailable(soundQueue)<2; #define BUFLEN 2048
static uint8_t buf[BUFLEN];
static volatile int wp=256, rp=0;
static int bufLen() {
return (wp-rp)&(BUFLEN-1);
} }
int sndDone() { //1 when stuff can be written to buffer
// printf("sndpoll %d\n", bufLen());
return bufLen()<(BUFLEN-400);
}
#define SND_CHUNKSZ 32 volatile static int myVolume;
int sndPush(uint8_t *data, int volume) {
uint32_t tmpb[SND_CHUNKSZ]; #define SND_CHUNKSZ 128
int i=0; void sndTask(void *arg) {
int len=370; uint32_t tmpb[SND_CHUNKSZ]={0};
while (i<len) { printf("Sound task started.\n");
int plen=len-i; while (1) {
if (plen>SND_CHUNKSZ) plen=SND_CHUNKSZ; int volume=(int)myVolume;
for (int j=0; j<plen; j++) { for (int j=0; j<SND_CHUNKSZ; j++) {
int s=*data; int s=buf[rp];
s=((s-128)>>(7-volume)); s=((s-128)>>(7-volume));
// s=s/16; s=s/16;
tmpb[j]=((s+128)<<8)+((s+128)<<24); tmpb[j]=((s+128)<<8)+((s+128)<<24);
data+=2; rp++;
if (rp>=BUFLEN) rp=0;
} }
i2s_write_bytes(0, (char*)tmpb, plen*4, portMAX_DELAY); i2s_write_bytes(0, (char*)tmpb, sizeof(tmpb), portMAX_DELAY);
i+=plen; // printf("snd %d\n", rp);
}
}
int sndPush(uint8_t *data, int volume) {
while (!sndDone()) usleep(1000);
myVolume=volume;
for (int i=0; i<370; i++) {
buf[wp]=*data;
data+=2;
wp++;
if (wp>=BUFLEN) wp=0;
} }
return 1; return 1;
} }
@ -38,13 +60,13 @@ int sndPush(uint8_t *data, int volume) {
void sndInit() { void sndInit() {
i2s_config_t cfg={ i2s_config_t cfg={
.mode=I2S_MODE_DAC_BUILT_IN|I2S_MODE_TX|I2S_MODE_MASTER, .mode=I2S_MODE_DAC_BUILT_IN|I2S_MODE_TX|I2S_MODE_MASTER,
.sample_rate=22000, .sample_rate=22200,
.bits_per_sample=16, .bits_per_sample=16,
.channel_format=I2S_CHANNEL_FMT_RIGHT_LEFT, .channel_format=I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format=I2S_COMM_FORMAT_I2S_MSB, .communication_format=I2S_COMM_FORMAT_I2S_MSB,
.intr_alloc_flags=0, .intr_alloc_flags=0,
.dma_buf_count=4, .dma_buf_count=8,
.dma_buf_len=1024/4 .dma_buf_len=1024/8
}; };
i2s_driver_install(0, &cfg, 4, &soundQueue); i2s_driver_install(0, &cfg, 4, &soundQueue);
i2s_set_pin(0, NULL); i2s_set_pin(0, NULL);
@ -63,6 +85,7 @@ void sndInit() {
}; };
gpio_config(&io_conf); gpio_config(&io_conf);
#endif #endif
xTaskCreatePinnedToCore(&sndTask, "snd", 3*1024, NULL, 6, NULL, 1);
} }

View File

@ -459,6 +459,7 @@ void printFps() {
void tmeStartEmu(void *rom) { void tmeStartEmu(void *rom) {
int ca1=0, ca2=0; int ca1=0, ca2=0;
int x, m=0, frame=0; int x, m=0, frame=0;
int cyclesPerSec=0;
macRom=rom; macRom=rom;
ramInit(); ramInit();
rom_remap=1; rom_remap=1;
@ -482,23 +483,23 @@ void tmeStartEmu(void *rom) {
localtalkInit(); localtalkInit();
printf("Done! Running.\n"); printf("Done! Running.\n");
while(1) { while(1) {
for (x=0; x<8000000/60; x+=10) { for (x=0; x<8000000/60; x+=1000) {
m68k_execute(10); for (int i=0; i<100; i++) {
viaStep(1); //should run at 783.36KHz m68k_execute(10);
sccTick(); viaStep(1); //should run at 783.36KHz
m++; sccTick();
if (m>=1000) {
int r=mouseTick();
if (r&MOUSE_BTN) viaClear(VIA_PORTB, (1<<3)); else viaSet(VIA_PORTB, (1<<3));
if (r&MOUSE_QXB) viaClear(VIA_PORTB, (1<<4)); else viaSet(VIA_PORTB, (1<<4));
if (r&MOUSE_QYB) viaClear(VIA_PORTB, (1<<5)); else viaSet(VIA_PORTB, (1<<5));
sccSetDcd(SCC_CHANA, r&MOUSE_QXA);
sccSetDcd(SCC_CHANB, r&MOUSE_QYA);
m=0;
} }
int r=mouseTick();
if (r&MOUSE_BTN) viaClear(VIA_PORTB, (1<<3)); else viaSet(VIA_PORTB, (1<<3));
if (r&MOUSE_QXB) viaClear(VIA_PORTB, (1<<4)); else viaSet(VIA_PORTB, (1<<4));
if (r&MOUSE_QYB) viaClear(VIA_PORTB, (1<<5)); else viaSet(VIA_PORTB, (1<<5));
sccSetDcd(SCC_CHANA, r&MOUSE_QXA);
sccSetDcd(SCC_CHANB, r&MOUSE_QYA);
m=0;
//Sound handler keeps track of real time, if its buffer is empty we should be done with the video frame. //Sound handler keeps track of real time, if its buffer is empty we should be done with the video frame.
//if (sndDone()) break; if (sndDone()) break;
} }
cyclesPerSec+=x;
dispDraw(macFb[video_remap?1:0]); dispDraw(macFb[video_remap?1:0]);
sndPush(macSnd[audio_remap?1:0], audio_en?audio_volume:0); sndPush(macSnd[audio_remap?1:0], audio_en?audio_volume:0);
localtalkTick(); localtalkTick();
@ -511,6 +512,8 @@ void tmeStartEmu(void *rom) {
rtcTick(); rtcTick();
frame=0; frame=0;
printFps(); printFps();
printf("%d Hz\n", cyclesPerSec);
cyclesPerSec=0;
} }
} }
} }