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;
ets_delay_us(100);
*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;
*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.
#else
#define SCALE_FACT 32
#endif
static uint8_t mask[512];
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!
#if 1
#if DO_RESCALE
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
@ -177,50 +180,88 @@ static void initLcd() {
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) {
uint8_t *img=malloc((LINESPERBUF*320*2)+1);
assert(img);
calcLut();
uint8_t cmd[5];
uint8_t *oldImg=malloc(512*342/8);
int firstrun=1;
setColRange(0, 319);
while(1) {
int l=0;
mipiResync();
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;
img[0]=0x2c;
uint8_t *p=&img[1];
for (int j=0; j<319; j++) {
for (int i=0; i<320; i++) {
int v=findPixelVal(myData, i, j);
*p++=(v&0xff);
*p++=(v>>8);
int xstart, xend, ystart, yend;
if (!firstrun) {
xstart=0; xend=320;
for (ystart=0; ystart<342; ystart++) {
if (memcmp(oldImg+64*ystart, myData+64*ystart, 64)!=0) break;
}
l++;
if (l>=LINESPERBUF || j==319) {
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;
for (yend=342-1; yend>=ystart; --yend) {
if (memcmp(oldImg+64*yend, myData+64*yend, 64)!=0) break;
}
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;
int sndDone() {
return uxQueueSpacesAvailable(soundQueue)<2;
//powers of 2 plzthx
#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
int sndPush(uint8_t *data, int volume) {
uint32_t tmpb[SND_CHUNKSZ];
int i=0;
int len=370;
while (i<len) {
int plen=len-i;
if (plen>SND_CHUNKSZ) plen=SND_CHUNKSZ;
for (int j=0; j<plen; j++) {
int s=*data;
volatile static int myVolume;
#define SND_CHUNKSZ 128
void sndTask(void *arg) {
uint32_t tmpb[SND_CHUNKSZ]={0};
printf("Sound task started.\n");
while (1) {
int volume=(int)myVolume;
for (int j=0; j<SND_CHUNKSZ; j++) {
int s=buf[rp];
s=((s-128)>>(7-volume));
// s=s/16;
s=s/16;
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);
i+=plen;
i2s_write_bytes(0, (char*)tmpb, sizeof(tmpb), portMAX_DELAY);
// 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;
}
@ -38,13 +60,13 @@ int sndPush(uint8_t *data, int volume) {
void sndInit() {
i2s_config_t cfg={
.mode=I2S_MODE_DAC_BUILT_IN|I2S_MODE_TX|I2S_MODE_MASTER,
.sample_rate=22000,
.sample_rate=22200,
.bits_per_sample=16,
.channel_format=I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format=I2S_COMM_FORMAT_I2S_MSB,
.intr_alloc_flags=0,
.dma_buf_count=4,
.dma_buf_len=1024/4
.dma_buf_count=8,
.dma_buf_len=1024/8
};
i2s_driver_install(0, &cfg, 4, &soundQueue);
i2s_set_pin(0, NULL);
@ -63,6 +85,7 @@ void sndInit() {
};
gpio_config(&io_conf);
#endif
xTaskCreatePinnedToCore(&sndTask, "snd", 3*1024, NULL, 6, NULL, 1);
}

View File

@ -459,6 +459,7 @@ void printFps() {
void tmeStartEmu(void *rom) {
int ca1=0, ca2=0;
int x, m=0, frame=0;
int cyclesPerSec=0;
macRom=rom;
ramInit();
rom_remap=1;
@ -482,23 +483,23 @@ void tmeStartEmu(void *rom) {
localtalkInit();
printf("Done! Running.\n");
while(1) {
for (x=0; x<8000000/60; x+=10) {
m68k_execute(10);
viaStep(1); //should run at 783.36KHz
sccTick();
m++;
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;
for (x=0; x<8000000/60; x+=1000) {
for (int i=0; i<100; i++) {
m68k_execute(10);
viaStep(1); //should run at 783.36KHz
sccTick();
}
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.
//if (sndDone()) break;
if (sndDone()) break;
}
cyclesPerSec+=x;
dispDraw(macFb[video_remap?1:0]);
sndPush(macSnd[audio_remap?1:0], audio_en?audio_volume:0);
localtalkTick();
@ -511,6 +512,8 @@ void tmeStartEmu(void *rom) {
rtcTick();
frame=0;
printFps();
printf("%d Hz\n", cyclesPerSec);
cyclesPerSec=0;
}
}
}