Speedups because direct pc-rel read/write, fix sound a bit

This commit is contained in:
Jeroen Domburg 2017-11-05 22:02:18 -08:00
parent feaa2434ea
commit ea1ed9972a
14 changed files with 151 additions and 63 deletions

View File

@ -231,8 +231,11 @@ static void IRAM_ATTR displayTask(void *arg) {
//No need for update
yend=342;
} else {
//Only copy changed bits of data to changebuffer
memcpy(oldImg+(ystart*64), myData+(ystart*64), (yend-ystart)*64);
ystart=(ystart*32)/SCALE_FACT-1;
yend=(yend*32)/SCALE_FACT+1;
yend=(yend*32)/SCALE_FACT+2;
if (ystart<0) ystart=0;
printf("Changed %d to %d\n", ystart, yend);
}
@ -248,7 +251,7 @@ static void IRAM_ATTR displayTask(void *arg) {
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);
int v=findPixelVal(oldImg, i, j);
*p++=(v&0xff);
*p++=(v>>8);
}

View File

@ -48,11 +48,19 @@ void sndTask(void *arg) {
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;
if (volume) {
for (int i=0; i<370; i++) {
buf[wp]=*data;
data+=2;
wp++;
if (wp>=BUFLEN) wp=0;
}
} else {
//muted
for (int i=0; i<370; i++) {
buf[wp++]=128;
if (wp>=BUFLEN) wp=0;
}
}
return 1;
}

View File

@ -7,14 +7,15 @@ 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 \
COMPONENT_OBJS := musashi/m68kops_pre.o musashi/m68kopac.o musashi/m68kopdm-iram.o musashi/m68kopnz.o musashi/m68kcpu-iram.o emu.o \
iwm.o via.o rtc.o ncr.o scc.o mouse.o
#nothing in iram: 16%
#nothing in iram: 1240000
#ac nz in iram: 19%
#dm nz in iram: 19%
#dm nz in iram: ng
#ac dm in iram: 23%
#dm in iram: 23%
#dm in iram: 1709000
#cpu in iram: 1278000
#-O3:
#nothing: 13%
@ -33,8 +34,9 @@ COMPONENT_EXTRA_CLEAN := $(addprefix $(COMPONENT_PATH)/musashi/,$(MUSASHI_GEN_SR
#musashi/m68kops_pre.o: CFLAGS += -O3
#musashi/m68kopac.o: CFLAGS += -O3
#musashi/m68kopdm.o: CFLAGS += -O3
musashi/m68kopdm.o: CFLAGS += -O3
#musashi/m68kopnz.o: CFLAGS += -O3
musashi/m68kcpu.o: CFLAGS += -O3
emu.o: CFLAGS += -O3

View File

@ -441,6 +441,22 @@ void m68k_write_memory_32(unsigned int address, unsigned int value) {
}
#endif
unsigned char *m68k_pcbase=NULL;
void m68k_pc_changed_handler_function(unsigned int address) {
// printf("m68k_pc_changed_handler_function %x\n", address);
const MemmapEnt *mmEnt=getMmmapEnt(address);
if (mmEnt->memAddr) {
uint8_t *p;
p=(uint8_t*)MMAP_RAM_PTR(mmEnt, address);
m68k_pcbase=p-address;
} else {
printf("PC not in mem!\n");
abort();
}
}
//Should be called every second.
void printFps() {
struct timeval tv;
@ -449,7 +465,7 @@ void printFps() {
if (oldtv.tv_sec!=0) {
long msec=(tv.tv_sec-oldtv.tv_sec)*1000;
msec+=(tv.tv_usec-oldtv.tv_usec)/1000;
// printf("Speed: %d%%\n", (int)(100000/msec));
printf("Speed: %d%%\n", (int)(100000/msec));
// printf("Mem free: %dKiB 8-bit, %dKiB 32-bit\n", xPortGetFreeHeapSizeCaps(MALLOC_CAP_8BIT)/1024, xPortGetFreeHeapSizeCaps(MALLOC_CAP_32BIT)/1024);
}
oldtv.tv_sec=tv.tv_sec;
@ -458,7 +474,7 @@ void printFps() {
void tmeStartEmu(void *rom) {
int ca1=0, ca2=0;
int x, m=0, frame=0;
int x, frame=0;
int cyclesPerSec=0;
macRom=rom;
ramInit();
@ -473,6 +489,7 @@ void tmeStartEmu(void *rom) {
viaSet(VIA_PORTB, (1<<3));
sccInit();
printf("Initializing m68k...\n");
m68k_pc_changed_handler_function(0x0);
m68k_init();
printf("Setting CPU type and resetting...");
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
@ -484,27 +501,24 @@ void tmeStartEmu(void *rom) {
printf("Done! Running.\n");
while(1) {
for (x=0; x<8000000/60; x+=1000) {
for (int i=0; i<10; i++) {
m68k_execute(100);
for (int l=0; l<10; l++) {
viaStep(1); //should run at 783.36KHz
sccTick();
}
}
m68k_execute(1000);
viaStep(100); //should run at 783.36KHz
sccTick(100);
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 (x>(8000000/120) && sndDone()) break;
}
cyclesPerSec+=x;
dispDraw(macFb[video_remap?1:0]);
sndPush(macSnd[audio_remap?1:0], audio_en?audio_volume:0);
localtalkTick();
// localtalkTick();
frame++;
ca1^=1;
viaControlWrite(VIA_CA1, ca1);
@ -513,8 +527,8 @@ void tmeStartEmu(void *rom) {
viaControlWrite(VIA_CA2, ca2);
rtcTick();
frame=0;
printFps();
printf("%d Hz\n", cyclesPerSec);
// printFps();
// printf("%d Hz\n", cyclesPerSec);
cyclesPerSec=0;
}
}
@ -532,17 +546,19 @@ void sccIrq(int req) {
void viaCbPortAWrite(unsigned int val) {
int oldRomRemap=rom_remap;
static int writes=0;
if ((writes++)==0) val=0x67;
printf("VIA PORTA WRITE %x\n", val);
video_remap=(val&(1<<6))?1:0;
rom_remap=(val&(1<<4))?1:0;
regenMemmap(rom_remap);
audio_remap=(val&(1<<3))?0:1;
if (oldRomRemap!=rom_remap) printf("ROM REMAP %d\n", rom_remap);
iwmSetHeadSel(val&(1<<5));
audio_remap=(val&(1<<3))?1:0;
audio_volume=(val&7);
iwmSetHeadSel(val&(1<<5));
regenMemmap(rom_remap);
}
void viaCbPortBWrite(unsigned int val) {
printf("VIA PORTB WRITE %x\n", val);
int b;
b=rtcCom(val&4, val&1, val&2);
if (b) viaSet(VIA_PORTB, 1); else viaClear(VIA_PORTB, 1);

View File

@ -73,7 +73,8 @@
* and m68k_read_pcrelative_xx() for PC-relative addressing.
* If off, all read requests from the CPU will be redirected to m68k_read_xx()
*/
#define M68K_SEPARATE_READS OPT_OFF
#define M68K_SEPARATE_READS OPT_ON
/* If ON, the CPU will call m68k_write_32_pd() when it executes move.l with a
* predecrement destination EA mode instead of m68k_write_32().
@ -124,9 +125,9 @@
* large value. This allows host programs to be nicer when it comes to
* fetching immediate data and instructions on a banked memory system.
*/
#define M68K_MONITOR_PC OPT_OFF
#define M68K_SET_PC_CALLBACK(A) your_pc_changed_handler_function(A)
#define M68K_MONITOR_PC OPT_SPECIFY_HANDLER
#define M68K_SET_PC_CALLBACK(A) m68k_pc_changed_handler_function(A)
void m68k_pc_changed_handler_function(unsigned int addr);
/* If ON, CPU will call the instruction hook callback before every
* instruction.
@ -185,4 +186,41 @@ void m68k_instruction();
/* ============================== END OF FILE ============================= */
/* ======================================================================== */
#include <byteswap.h>
#include <stdint.h>
extern unsigned char *m68k_pcbase;
static inline unsigned int m68k_read_immediate_16(unsigned int address) {
address&=0xFFFFFF;
uint16_t *p=(uint16_t*)(m68k_pcbase+address);
return __bswap_16(*p);
}
static inline unsigned int m68k_read_immediate_32(unsigned int address) {
address&=0xFFFFFF;
uint32_t *p=(uint32_t*)(m68k_pcbase+address);
return __bswap_32(*p);
}
static inline unsigned int m68k_read_pcrelative_8(unsigned int address) {
address&=0xFFFFFF;
uint8_t *p=(uint8_t*)(m68k_pcbase+address);
return *p;
}
static inline unsigned int m68k_read_pcrelative_16(unsigned int address) {
address&=0xFFFFFF;
uint16_t *p=(uint16_t*)(m68k_pcbase+address);
return __bswap_16(*p);
}
static inline unsigned int m68k_read_pcrelative_32(unsigned int address) {
address&=0xFFFFFF;
uint32_t *p=(uint32_t*)(m68k_pcbase+address);
return __bswap_32(*p);
}
#endif /* M68KCONF__HEADER */

View File

@ -161,6 +161,7 @@ unsigned int m68k_read_memory_8(unsigned int address);
unsigned int m68k_read_memory_16(unsigned int address);
unsigned int m68k_read_memory_32(unsigned int address);
#if 0
/* Read data immediately following the PC */
unsigned int m68k_read_immediate_16(unsigned int address);
unsigned int m68k_read_immediate_32(unsigned int address);
@ -169,6 +170,7 @@ unsigned int m68k_read_immediate_32(unsigned int address);
unsigned int m68k_read_pcrelative_8(unsigned int address);
unsigned int m68k_read_pcrelative_16(unsigned int address);
unsigned int m68k_read_pcrelative_32(unsigned int address);
#endif
/* Memory access for the disassembler */
unsigned int m68k_read_disassembler_8 (unsigned int address);

View File

@ -39,7 +39,7 @@ int rtcCom(int en, int dat, int clk) {
} else if (rtc.pos==15) {
if ((rtc.cmd&0x8000)==0) {
rtc.mem[(rtc.cmd&0x7C00)>>10]=rtc.cmd&0xff;
// saveRtcMem(rtc.mem);
saveRtcMem(rtc.mem);
}
printf("RTC/PRAM CMD %x\n", rtc.cmd);
}

View File

@ -111,10 +111,11 @@ static int rxBytesLeft(int chan) {
return scc.chan[chan].rx[scc.chan[chan].rxBufCur].len-scc.chan[chan].rxPos;
}
static int rxBufTick(int chan) {
static int rxBufTick(int chan, int noTicks) {
if (scc.chan[chan].rx[scc.chan[chan].rxBufCur].delay > 0) {
scc.chan[chan].rx[scc.chan[chan].rxBufCur].delay--;
if (scc.chan[chan].rx[scc.chan[chan].rxBufCur].delay==0) {
scc.chan[chan].rx[scc.chan[chan].rxBufCur].delay-=noTicks;
if (scc.chan[chan].rx[scc.chan[chan].rxBufCur].delay<=0) {
scc.chan[chan].rx[scc.chan[chan].rxBufCur].delay=0;
#ifdef SCC_DBG
printf("Feeding buffer %d into SCC\n", scc.chan[chan].rxBufCur);
#endif
@ -592,30 +593,40 @@ unsigned int sccRead(unsigned int addr) {
}
//Called at about 800KHz
void sccTick() {
void sccTick(int noTicks) {
for (int n=0; n<2; n++) {
int needCheck=0;
if (scc.chan[n].txTimer>0) {
scc.chan[n].txTimer--;
if (scc.chan[n].txTimer==0) {
scc.chan[n].txTimer-=noTicks;
if (scc.chan[n].txTimer<=0) {
scc.chan[n].txTimer=0;
// printf("Tx buffer empty: Sent data\n");
sccTxFinished(n);
needCheck=1;
}
}
if (rxBufTick(n)) {
if (rxBufTick(n, noTicks)) {
triggerRx(n);
needCheck=1;
}
if (scc.chan[n].eofDelay>0) {
scc.chan[n].eofDelay--;
scc.chan[n].eofDelay-=noTicks;
if (scc.chan[n].eofDelay<0) scc.chan[n].eofDelay=0;
if (scc.chan[n].eofDelay==0 && (scc.chan[n].wr1&0x10)!=0) {
//Int mode is recv char or special / special only
printf("Raise EOF int for channel %d\n", n);
scc.chan[n].eofIntPending=1;
scc.intpending|=((n==0)?SCC_RR3_CHA_RX:SCC_RR3_CHB_RX);
raiseInt(n);
needCheck=1;
}
}
if (scc.chan[n].rxAbrtTimer>0) scc.chan[n].rxAbrtTimer--;
checkExtInt(n);
if (scc.chan[n].rxAbrtTimer>0) {
scc.chan[n].rxAbrtTimer-=noTicks;
if (scc.chan[n].rxAbrtTimer<0) scc.chan[n].rxAbrtTimer=0;
needCheck=1;
}
if (needCheck) checkExtInt(n);
}
}

View File

@ -6,6 +6,6 @@ void sccWrite(unsigned int addr, unsigned int val);
unsigned int sccRead(unsigned int addr);
void sccSetDcd(int chan, int val);
void sccInit();
void sccTick();
void sccTick(int cycles);
void sccRecv(int chan, uint8_t *data, int len, int delay);

View File

@ -17,13 +17,16 @@ void sdlDie() {
void dispInit() {
if (SDL_Init( SDL_INIT_VIDEO|SDL_INIT_AUDIO ) < 0 ) sdlDie();
win=SDL_CreateWindow( "TME", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
if (win==0) sdlDie();
surf=SDL_GetWindowSurface(win);
drwsurf=SDL_CreateRGBSurfaceWithFormat(0, SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_PIXELFORMAT_RGBA32);
}
void sdlDispAudioInit() {
if (SDL_Init( SDL_INIT_VIDEO|SDL_INIT_AUDIO ) < 0 ) sdlDie();
}
void handleInput() {
static int btn=0;
static int oldx, oldy;

View File

@ -8,6 +8,7 @@
#include <unistd.h>
#include "tmeconfig.h"
#include "snd.h"
#include "disp.h"
static void *loadRom(char *file) {
int i;
@ -38,5 +39,6 @@ int main(int argc, char **argv) {
rtcInit(data);
fclose(f);
}
sdlDispAudioInit();
tmeStartEmu(rom);
}

View File

@ -15,7 +15,7 @@ static int bufLen() {
}
int sndDone() {
if (!soundEna) return 1;
if (!soundEna) return 0;
return (bufLen()<512);
}

View File

@ -29,7 +29,6 @@
#define TME_SCREENBUF 0x3FA700
#define TME_SCREENBUF_ALT 0x3F2700
#define TME_SNDBUF 0x3FFD00
#define TME_SNDBUF_ALT 0x3FA100
#else
@ -40,9 +39,9 @@
#define TME_SCREENBUF 0x1A700
#define TME_SCREENBUF_ALT 0x12700
#define TME_SNDBUF 0x1FD00
#define TME_SNDBUF_ALT 0x1A100
#endif
#endif
#endif
//Source: Guide to the Macintosh family hardware
#define TME_SNDBUF_ALT (TME_SNDBUF-0x5C00)

View File

@ -30,7 +30,7 @@ typedef struct {
uint8_t ddra, ddrb;
uint8_t ina, inb;
uint8_t outa, outb;
uint16_t timer1, timer2;
int timer1, timer2;
uint16_t latch1, latch2;
uint8_t ifr, ier;
uint8_t pcr, acr;
@ -54,18 +54,19 @@ void viaClear(int no, int mask) {
}
void viaStep(int clockcycles) {
while(clockcycles--) {
if (via.timer1==1) {
if ((via.timer1!=0) || (via.acr&(1<<6))) {
via.timer1-=clockcycles;
if (via.timer1<=1) {
via.ifr|=IFR_T1;
via.timer1=via.latch1;
}
if ((via.timer1!=0) || (via.acr&(1<<6))) via.timer1--;
via.timer2--;
if (via.timer2==0) {
//Actually shouldn't be set when timer2 gets 0 a 2nd time... ahwell.
via.ifr|=IFR_T2;
via.timer1+=via.latch1;
}
}
via.timer2-=clockcycles;
if (via.timer2<=0) {
//Actually shouldn't be set when timer2 gets 0 a 2nd time... ahwell.
via.ifr|=IFR_T2;
via.timer2+=0x10000;
}
}
static void viaCheckIrq() {
@ -119,10 +120,12 @@ void viaWrite(unsigned int addr, unsigned int val) {
if (addr==0x0) {
//ORB
viaCbPortBWrite(val);
via.inb=(via.inb&~via.ddrb)|(val&via.ddrb);
accessPort(1);
} else if (addr==0x1) {
//ORA
viaCbPortAWrite(val);
via.ina=(via.ina&~via.ddra)|(val&via.ddra);
accessPort(0);
} else if (addr==0x2) {
//DDRB
@ -180,6 +183,7 @@ void viaWrite(unsigned int addr, unsigned int val) {
} else if (addr==0xf) {
//ORA
viaCbPortAWrite(val);
via.ina=(via.ina&~via.ddra)|(val&via.ddra);
}
// printf("VIA write %s val %x\n", viaRegNames[addr], val);
}