mirror of
https://github.com/Spritetm/minimacplus.git
synced 2024-12-29 09:30:04 +00:00
Get sound working; add partial updates (scanlines) to gfx driver
This commit is contained in:
parent
d7e63ad200
commit
36dcd10658
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user