Oled hackery, attempt at native sound
This commit is contained in:
parent
8c0309aee1
commit
fa6a9ae5b7
|
@ -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);
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue