Oled hackery, attempt at native sound

This commit is contained in:
Jeroen Domburg 2017-10-22 21:20:04 +08:00
parent 8c0309aee1
commit fa6a9ae5b7
9 changed files with 142 additions and 22 deletions

View File

@ -0,0 +1,17 @@
#include <stdint.h>
//All stubbed out for now.
void localtalkSend(uint8_t *data, int len) {
}
void localtalkInit() {
}
void localtalkTick() {
}
//void localtalk_send_llap_resp(uint8_t node);

View File

@ -115,6 +115,8 @@ 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
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 sy=(y*SCALE_FACT);
@ -134,6 +136,15 @@ static int IRAM_ATTR findPixelVal(uint8_t *data, int x, int y) {
return ((r>>5)<<0)|((g>>4)<<5)|((b>>5)<<11);
}
#else
//Stupid 1-to-1 routine
static int IRAM_ATTR findPixelVal(uint8_t *data, int x, int y) {
return (data[y*32+(x>>3)]&(1<<(x&7)))?0:0xffff;
}
#endif
volatile static uint8_t *currFbPtr=NULL;
SemaphoreHandle_t dispSem = NULL;
@ -143,19 +154,25 @@ static void initLcd() {
mipiInit();
vTaskDelay(20/portTICK_RATE_MS); //give screen a sec
for (int j=0; j<2; j++) { //Init multiple times; for mysterious reasons it sometimes doesn't catch first time.
for (int i=0; initPackets[i].type!=0; i++) {
mipiResync();
if (initPackets[i].type==0x39 || initPackets[i].type==0x29) {
uint8_t data[17];
data[0]=initPackets[i].addr;
memcpy(data+1, initPackets[i].data, 16);
mipiDsiSendLong(initPackets[i].type, data, initPackets[i].len+1);
} else {
uint8_t data[2]={initPackets[i].addr, initPackets[i].data[0]};
mipiDsiSendShort(initPackets[i].type, data, initPackets[i].len+1);
if (initPackets[i].type==5) vTaskDelay(300/portTICK_RATE_MS);
for (int i=0; initPackets[i].type!=0; i++) {
mipiResync();
if (initPackets[i].type==0x39 || initPackets[i].type==0x29) {
uint8_t data[17];
data[0]=initPackets[i].addr;
memcpy(data+1, initPackets[i].data, 16);
mipiDsiSendLong(initPackets[i].type, data, initPackets[i].len+1);
} else {
uint8_t data[2]={initPackets[i].addr, initPackets[i].data[0]};
mipiDsiSendShort(initPackets[i].type, data, initPackets[i].len+1);
if (initPackets[i].type==5) vTaskDelay(300/portTICK_RATE_MS);
}
}
}
uint8_t clrData[33]={0x2c, 0, 0, 0};
for (int i=0; i<(320*340*2)/32; i++) {
mipiDsiSendLong(0x39, clrData, 32);
clrData[0]=0x3C;
}
printf("Display inited.\n");
}
@ -164,12 +181,21 @@ static void IRAM_ATTR displayTask(void *arg) {
uint8_t *img=malloc((LINESPERBUF*320*2)+1);
assert(img);
calcLut();
uint8_t cmd[5];
int firstrun=1;
while(1) {
int l=0;
mipiResync();
xSemaphoreTake(dispSem, portMAX_DELAY);
#if 0
cmd[0]=0x2a; //set_col_addr
cmd[1]=0; //scolh
cmd[2]=0; //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];
@ -206,7 +232,6 @@ void dispDraw(uint8_t *mem) {
void dispInit() {
initLcd();
printf("spi_lcd_init()\n");
int ret=adns9500_init();
if (!ret) printf("No mouse found!\n");

View File

@ -0,0 +1,68 @@
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include <driver/i2s.h>
static QueueHandle_t soundQueue;
int sndDone() {
return uxQueueSpacesAvailable(soundQueue)<2;
}
#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;
s=((s-128)>>(7-volume));
// s=s/16;
tmpb[j]=((s+128)<<8)+((s+128)<<24);
data+=2;
}
i2s_write_bytes(0, (char*)tmpb, plen*4, portMAX_DELAY);
i+=plen;
}
return 1;
}
void sndInit() {
i2s_config_t cfg={
.mode=I2S_MODE_DAC_BUILT_IN|I2S_MODE_TX|I2S_MODE_MASTER,
.sample_rate=22000,
.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
};
i2s_driver_install(0, &cfg, 4, &soundQueue);
i2s_set_pin(0, NULL);
i2s_set_dac_mode(I2S_DAC_CHANNEL_LEFT_EN);
i2s_set_sample_rates(0, cfg.sample_rate);
#if 1
//I2S enables *both* DAC channels; we only need DAC2. DAC1 is connected to the select button.
CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_DAC_XPD_FORCE_M);
CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_XPD_DAC_M);
gpio_config_t io_conf={
.intr_type=GPIO_INTR_DISABLE,
.mode=GPIO_MODE_INPUT,
.pull_up_en=1,
.pin_bit_mask=(1<<25)
};
gpio_config(&io_conf);
#endif
}

View File

@ -8,7 +8,7 @@ COMPONENT_SRCDIRS := . musashi
MUSASHI_GEN_SRC := musashi/m68kops_pre.c musashi/m68kopac.c musashi/m68kopdm.c musashi/m68kopnz.c
MUSASHI_GEN_OBJ := $(MUSASHI_GEN_SRC:%.c=%.o)
COMPONENT_OBJS := musashi/m68kops_pre.o musashi/m68kopac.o musashi/m68kopdm-iram.o musashi/m68kopnz.o musashi/m68kcpu.o emu.o \
iwm.o via.o rtc.o ncr.o scc.o mouse.o network/localtalk.o network/ddp.o network/ethertalk.o
iwm.o via.o rtc.o ncr.o scc.o mouse.o
#nothing in iram: 16%
#ac nz in iram: 19%
@ -59,7 +59,7 @@ $(COMPONENT_PATH)/musashi/m68kop%.c: $(COMPONENT_PATH)/musashi/m68kmake
$(COMPONENT_PATH)/musashi/m68kops_pre.c: $(COMPONENT_PATH)/musashi/m68kops_gen
cd $(COMPONENT_PATH)/musashi/; ./m68kops_gen > m68kops_pre.c
$(COMPONENT_PATH)/musashi/m68kops_gen: $(COMPONENT_PATH)/musashi/m68kops_gen.c
$(COMPONENT_PATH)/musashi/m68kops_gen: $(COMPONENT_PATH)/musashi/m68kops.c
cd $(COMPONENT_PATH)/musashi/; $(HOSTCC) -std=gnu99 -o m68kops_gen m68kops.c
$(COMPONENT_PATH)/musashi/m68kmake: $(COMPONENT_PATH)/musashi/m68kmake.c

View File

@ -319,10 +319,10 @@ static void ramInit() {
#endif
}
#else
#else //!USE_EXTERNAL_RAM
#define MMAP_RAM_PTR(ent, addr) &ent->memAddr[addr&(MEMMAP_ES-1)]
static void ramInit() {
printf("Using internal memory as Mac RAM\n");
printf("Using internal (or hw cached) memory as Mac RAM\n");
#if CONFIG_SPIRAM_USE_MEMMAP
macRam=(void*)0x3F800000;
#else
@ -477,8 +477,8 @@ void tmeStartEmu(void *rom) {
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
m68k_pulse_reset();
printf("Display init...\n");
dispInit();
sndInit();
dispInit();
localtalkInit();
printf("Done! Running.\n");
while(1) {
@ -497,7 +497,7 @@ void tmeStartEmu(void *rom) {
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;
}
dispDraw(macFb[video_remap?1:0]);
sndPush(macSnd[audio_remap?1:0], audio_en?audio_volume:0);

View File

@ -86,7 +86,7 @@ void localtalk_send_ddp(uint8_t *data, int len) {
sccRecv(1, &rts, 3, 60);
//We assume this is a long ddp packet.
#if 1
#if 0
llap_packet_t *p=bufferedPacket;
p->destid=ddp_get_dest_node(data);
p->srcid=ddp_get_src_node(data);

View File

@ -460,13 +460,13 @@ unsigned int sccRead(unsigned int addr) {
//rx buffer
if (rxHasByte(chan)) {
int left;
int left=0;
val=rxByte(chan, &left);
printf("SCC READ DATA val %x, %d bytes left\n", val, left);
if (left==1) { //because status goes with byte *to be read*, the last byte here is the EOM byte
printf("Setting EOM\n");
scc.chan[chan].rxEom=1;
scc.chan[chan].rxAbrtTimer=20;
scc.chan[chan].rxAbrtTimer=40;
} else {
scc.chan[chan].rxEom=0;
}

View File

@ -8,15 +8,19 @@
static uint8_t buf[1024];
static int wp=256, rp=0;
static int soundEna=0;
static int bufLen() {
return (wp-rp)&1023;
}
int sndDone() {
if (!soundEna) return 1;
return (bufLen()<512);
}
int sndPush(uint8_t *data, int volume) {
if (!soundEna) return 0;
while(!sndDone()) usleep(1000);
for (int i=0; i<370; i++) {
int s=*data;
@ -25,6 +29,7 @@ int sndPush(uint8_t *data, int volume) {
if (wp==1024) wp=0;
data+=2;
}
return 1;
}
static void sndCb(void* userdata, Uint8* stream, int len) {
@ -48,8 +53,10 @@ void sndInit() {
dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0);
if (dev == 0) {
SDL_Log("Failed to open audio: %s", SDL_GetError());
} else {
SDL_PauseAudioDevice(dev, 0);
soundEna=1;
}
SDL_PauseAudioDevice(dev, 0);
}

View File

@ -39,6 +39,9 @@
#define TME_RAMSIZE (128*1024)
#define TME_SCREENBUF 0x1A700
#define TME_SCREENBUF_ALT 0x12700
#define TME_SNDBUF 0x1FD00
#define TME_SNDBUF_ALT 0x1A100
#endif