From fa6a9ae5b764a5462e3a30538f41dac98eb6faa2 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Sun, 22 Oct 2017 21:20:04 +0800 Subject: [PATCH] Oled hackery, attempt at native sound --- components/tme-esp32/localtalk.c | 17 ++++++++ components/tme-esp32/mipi_lcd.c | 49 +++++++++++++++------ components/tme-esp32/snd.c | 68 ++++++++++++++++++++++++++++++ components/tme/component.mk | 4 +- components/tme/emu.c | 8 ++-- components/tme/network/localtalk.c | 2 +- components/tme/scc.c | 4 +- components/tme/sdl/snd.c | 9 +++- components/tme/tmeconfig.h | 3 ++ 9 files changed, 142 insertions(+), 22 deletions(-) create mode 100644 components/tme-esp32/localtalk.c create mode 100644 components/tme-esp32/snd.c diff --git a/components/tme-esp32/localtalk.c b/components/tme-esp32/localtalk.c new file mode 100644 index 0000000..f4da394 --- /dev/null +++ b/components/tme-esp32/localtalk.c @@ -0,0 +1,17 @@ +#include + +//All stubbed out for now. + +void localtalkSend(uint8_t *data, int len) { + +} + +void localtalkInit() { + +} + +void localtalkTick() { + +} + +//void localtalk_send_llap_resp(uint8_t node); diff --git a/components/tme-esp32/mipi_lcd.c b/components/tme-esp32/mipi_lcd.c index 96746a6..29023b5 100644 --- a/components/tme-esp32/mipi_lcd.c +++ b/components/tme-esp32/mipi_lcd.c @@ -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"); diff --git a/components/tme-esp32/snd.c b/components/tme-esp32/snd.c new file mode 100644 index 0000000..a214909 --- /dev/null +++ b/components/tme-esp32/snd.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include + +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 (iSND_CHUNKSZ) plen=SND_CHUNKSZ; + for (int j=0; j>(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 +} + + diff --git a/components/tme/component.mk b/components/tme/component.mk index d6a0b68..b09a9f1 100644 --- a/components/tme/component.mk +++ b/components/tme/component.mk @@ -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 diff --git a/components/tme/emu.c b/components/tme/emu.c index 53ba515..817a828 100644 --- a/components/tme/emu.c +++ b/components/tme/emu.c @@ -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); diff --git a/components/tme/network/localtalk.c b/components/tme/network/localtalk.c index 0ef91d5..9660da4 100644 --- a/components/tme/network/localtalk.c +++ b/components/tme/network/localtalk.c @@ -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); diff --git a/components/tme/scc.c b/components/tme/scc.c index 5bf2ade..3ab5de8 100644 --- a/components/tme/scc.c +++ b/components/tme/scc.c @@ -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; } diff --git a/components/tme/sdl/snd.c b/components/tme/sdl/snd.c index 53dc688..342f5c1 100644 --- a/components/tme/sdl/snd.c +++ b/components/tme/sdl/snd.c @@ -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); } diff --git a/components/tme/tmeconfig.h b/components/tme/tmeconfig.h index eb7c1d3..3b9a87e 100644 --- a/components/tme/tmeconfig.h +++ b/components/tme/tmeconfig.h @@ -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