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 //No need for update
yend=342; yend=342;
} else { } 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; ystart=(ystart*32)/SCALE_FACT-1;
yend=(yend*32)/SCALE_FACT+1; yend=(yend*32)/SCALE_FACT+2;
if (ystart<0) ystart=0; if (ystart<0) ystart=0;
printf("Changed %d to %d\n", ystart, yend); printf("Changed %d to %d\n", ystart, yend);
} }
@ -248,7 +251,7 @@ static void IRAM_ATTR displayTask(void *arg) {
uint8_t *p=&img[1]; uint8_t *p=&img[1];
for (int j=ystart; j<yend; j++) { for (int j=ystart; j<yend; j++) {
for (int i=0; i<320; i++) { for (int i=0; i<320; i++) {
int v=findPixelVal(myData, i, j); int v=findPixelVal(oldImg, i, j);
*p++=(v&0xff); *p++=(v&0xff);
*p++=(v>>8); *p++=(v>>8);
} }

View File

@ -48,11 +48,19 @@ void sndTask(void *arg) {
int sndPush(uint8_t *data, int volume) { int sndPush(uint8_t *data, int volume) {
while (!sndDone()) usleep(1000); while (!sndDone()) usleep(1000);
myVolume=volume; myVolume=volume;
for (int i=0; i<370; i++) { if (volume) {
buf[wp]=*data; for (int i=0; i<370; i++) {
data+=2; buf[wp]=*data;
wp++; data+=2;
if (wp>=BUFLEN) wp=0; 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; 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_SRC := musashi/m68kops_pre.c musashi/m68kopac.c musashi/m68kopdm.c musashi/m68kopnz.c
MUSASHI_GEN_OBJ := $(MUSASHI_GEN_SRC:%.c=%.o) 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 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% #ac nz in iram: 19%
#dm nz in iram: 19% #dm nz in iram: ng
#ac dm in iram: 23% #ac dm in iram: 23%
#dm in iram: 23% #dm in iram: 1709000
#cpu in iram: 1278000
#-O3: #-O3:
#nothing: 13% #nothing: 13%
@ -33,8 +34,9 @@ COMPONENT_EXTRA_CLEAN := $(addprefix $(COMPONENT_PATH)/musashi/,$(MUSASHI_GEN_SR
#musashi/m68kops_pre.o: CFLAGS += -O3 #musashi/m68kops_pre.o: CFLAGS += -O3
#musashi/m68kopac.o: CFLAGS += -O3 #musashi/m68kopac.o: CFLAGS += -O3
#musashi/m68kopdm.o: CFLAGS += -O3 musashi/m68kopdm.o: CFLAGS += -O3
#musashi/m68kopnz.o: CFLAGS += -O3 #musashi/m68kopnz.o: CFLAGS += -O3
musashi/m68kcpu.o: CFLAGS += -O3
emu.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 #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. //Should be called every second.
void printFps() { void printFps() {
struct timeval tv; struct timeval tv;
@ -449,7 +465,7 @@ void printFps() {
if (oldtv.tv_sec!=0) { if (oldtv.tv_sec!=0) {
long msec=(tv.tv_sec-oldtv.tv_sec)*1000; long msec=(tv.tv_sec-oldtv.tv_sec)*1000;
msec+=(tv.tv_usec-oldtv.tv_usec)/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); // 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; oldtv.tv_sec=tv.tv_sec;
@ -458,7 +474,7 @@ void printFps() {
void tmeStartEmu(void *rom) { void tmeStartEmu(void *rom) {
int ca1=0, ca2=0; int ca1=0, ca2=0;
int x, m=0, frame=0; int x, frame=0;
int cyclesPerSec=0; int cyclesPerSec=0;
macRom=rom; macRom=rom;
ramInit(); ramInit();
@ -473,6 +489,7 @@ void tmeStartEmu(void *rom) {
viaSet(VIA_PORTB, (1<<3)); viaSet(VIA_PORTB, (1<<3));
sccInit(); sccInit();
printf("Initializing m68k...\n"); printf("Initializing m68k...\n");
m68k_pc_changed_handler_function(0x0);
m68k_init(); m68k_init();
printf("Setting CPU type and resetting..."); printf("Setting CPU type and resetting...");
m68k_set_cpu_type(M68K_CPU_TYPE_68000); m68k_set_cpu_type(M68K_CPU_TYPE_68000);
@ -484,27 +501,24 @@ void tmeStartEmu(void *rom) {
printf("Done! Running.\n"); printf("Done! Running.\n");
while(1) { while(1) {
for (x=0; x<8000000/60; x+=1000) { for (x=0; x<8000000/60; x+=1000) {
for (int i=0; i<10; i++) { m68k_execute(1000);
m68k_execute(100); viaStep(100); //should run at 783.36KHz
for (int l=0; l<10; l++) { sccTick(100);
viaStep(1); //should run at 783.36KHz
sccTick();
}
}
int r=mouseTick(); int r=mouseTick();
if (r&MOUSE_BTN) viaClear(VIA_PORTB, (1<<3)); else viaSet(VIA_PORTB, (1<<3)); 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_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)); if (r&MOUSE_QYB) viaClear(VIA_PORTB, (1<<5)); else viaSet(VIA_PORTB, (1<<5));
sccSetDcd(SCC_CHANA, r&MOUSE_QXA); sccSetDcd(SCC_CHANA, r&MOUSE_QXA);
sccSetDcd(SCC_CHANB, r&MOUSE_QYA); 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. //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; cyclesPerSec+=x;
dispDraw(macFb[video_remap?1:0]); dispDraw(macFb[video_remap?1:0]);
sndPush(macSnd[audio_remap?1:0], audio_en?audio_volume:0); sndPush(macSnd[audio_remap?1:0], audio_en?audio_volume:0);
localtalkTick(); // localtalkTick();
frame++; frame++;
ca1^=1; ca1^=1;
viaControlWrite(VIA_CA1, ca1); viaControlWrite(VIA_CA1, ca1);
@ -513,8 +527,8 @@ void tmeStartEmu(void *rom) {
viaControlWrite(VIA_CA2, ca2); viaControlWrite(VIA_CA2, ca2);
rtcTick(); rtcTick();
frame=0; frame=0;
printFps(); // printFps();
printf("%d Hz\n", cyclesPerSec); // printf("%d Hz\n", cyclesPerSec);
cyclesPerSec=0; cyclesPerSec=0;
} }
} }
@ -532,17 +546,19 @@ void sccIrq(int req) {
void viaCbPortAWrite(unsigned int val) { 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; video_remap=(val&(1<<6))?1:0;
rom_remap=(val&(1<<4))?1:0; rom_remap=(val&(1<<4))?1:0;
regenMemmap(rom_remap); audio_remap=(val&(1<<3))?1:0;
audio_remap=(val&(1<<3))?0:1;
if (oldRomRemap!=rom_remap) printf("ROM REMAP %d\n", rom_remap);
iwmSetHeadSel(val&(1<<5));
audio_volume=(val&7); audio_volume=(val&7);
iwmSetHeadSel(val&(1<<5));
regenMemmap(rom_remap);
} }
void viaCbPortBWrite(unsigned int val) { void viaCbPortBWrite(unsigned int val) {
printf("VIA PORTB WRITE %x\n", val);
int b; int b;
b=rtcCom(val&4, val&1, val&2); b=rtcCom(val&4, val&1, val&2);
if (b) viaSet(VIA_PORTB, 1); else viaClear(VIA_PORTB, 1); 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. * and m68k_read_pcrelative_xx() for PC-relative addressing.
* If off, all read requests from the CPU will be redirected to m68k_read_xx() * 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 /* 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(). * 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 * large value. This allows host programs to be nicer when it comes to
* fetching immediate data and instructions on a banked memory system. * fetching immediate data and instructions on a banked memory system.
*/ */
#define M68K_MONITOR_PC OPT_OFF #define M68K_MONITOR_PC OPT_SPECIFY_HANDLER
#define M68K_SET_PC_CALLBACK(A) your_pc_changed_handler_function(A) #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 /* If ON, CPU will call the instruction hook callback before every
* instruction. * instruction.
@ -185,4 +186,41 @@ void m68k_instruction();
/* ============================== END OF FILE ============================= */ /* ============================== 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 */ #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_16(unsigned int address);
unsigned int m68k_read_memory_32(unsigned int address); unsigned int m68k_read_memory_32(unsigned int address);
#if 0
/* Read data immediately following the PC */ /* Read data immediately following the PC */
unsigned int m68k_read_immediate_16(unsigned int address); unsigned int m68k_read_immediate_16(unsigned int address);
unsigned int m68k_read_immediate_32(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_8(unsigned int address);
unsigned int m68k_read_pcrelative_16(unsigned int address); unsigned int m68k_read_pcrelative_16(unsigned int address);
unsigned int m68k_read_pcrelative_32(unsigned int address); unsigned int m68k_read_pcrelative_32(unsigned int address);
#endif
/* Memory access for the disassembler */ /* Memory access for the disassembler */
unsigned int m68k_read_disassembler_8 (unsigned int address); 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) { } else if (rtc.pos==15) {
if ((rtc.cmd&0x8000)==0) { if ((rtc.cmd&0x8000)==0) {
rtc.mem[(rtc.cmd&0x7C00)>>10]=rtc.cmd&0xff; rtc.mem[(rtc.cmd&0x7C00)>>10]=rtc.cmd&0xff;
// saveRtcMem(rtc.mem); saveRtcMem(rtc.mem);
} }
printf("RTC/PRAM CMD %x\n", rtc.cmd); 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; 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) { if (scc.chan[chan].rx[scc.chan[chan].rxBufCur].delay > 0) {
scc.chan[chan].rx[scc.chan[chan].rxBufCur].delay--; scc.chan[chan].rx[scc.chan[chan].rxBufCur].delay-=noTicks;
if (scc.chan[chan].rx[scc.chan[chan].rxBufCur].delay==0) { if (scc.chan[chan].rx[scc.chan[chan].rxBufCur].delay<=0) {
scc.chan[chan].rx[scc.chan[chan].rxBufCur].delay=0;
#ifdef SCC_DBG #ifdef SCC_DBG
printf("Feeding buffer %d into SCC\n", scc.chan[chan].rxBufCur); printf("Feeding buffer %d into SCC\n", scc.chan[chan].rxBufCur);
#endif #endif
@ -592,30 +593,40 @@ unsigned int sccRead(unsigned int addr) {
} }
//Called at about 800KHz //Called at about 800KHz
void sccTick() { void sccTick(int noTicks) {
for (int n=0; n<2; n++) { for (int n=0; n<2; n++) {
int needCheck=0;
if (scc.chan[n].txTimer>0) { if (scc.chan[n].txTimer>0) {
scc.chan[n].txTimer--; scc.chan[n].txTimer-=noTicks;
if (scc.chan[n].txTimer==0) { if (scc.chan[n].txTimer<=0) {
scc.chan[n].txTimer=0;
// printf("Tx buffer empty: Sent data\n"); // printf("Tx buffer empty: Sent data\n");
sccTxFinished(n); sccTxFinished(n);
needCheck=1;
} }
} }
if (rxBufTick(n)) { if (rxBufTick(n, noTicks)) {
triggerRx(n); triggerRx(n);
needCheck=1;
} }
if (scc.chan[n].eofDelay>0) { 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) { if (scc.chan[n].eofDelay==0 && (scc.chan[n].wr1&0x10)!=0) {
//Int mode is recv char or special / special only //Int mode is recv char or special / special only
printf("Raise EOF int for channel %d\n", n); printf("Raise EOF int for channel %d\n", n);
scc.chan[n].eofIntPending=1; scc.chan[n].eofIntPending=1;
scc.intpending|=((n==0)?SCC_RR3_CHA_RX:SCC_RR3_CHB_RX); scc.intpending|=((n==0)?SCC_RR3_CHA_RX:SCC_RR3_CHB_RX);
raiseInt(n); raiseInt(n);
needCheck=1;
} }
} }
if (scc.chan[n].rxAbrtTimer>0) scc.chan[n].rxAbrtTimer--; if (scc.chan[n].rxAbrtTimer>0) {
checkExtInt(n); 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); unsigned int sccRead(unsigned int addr);
void sccSetDcd(int chan, int val); void sccSetDcd(int chan, int val);
void sccInit(); void sccInit();
void sccTick(); void sccTick(int cycles);
void sccRecv(int chan, uint8_t *data, int len, int delay); void sccRecv(int chan, uint8_t *data, int len, int delay);

View File

@ -17,13 +17,16 @@ void sdlDie() {
void dispInit() { 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 ); win=SDL_CreateWindow( "TME", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
if (win==0) sdlDie(); if (win==0) sdlDie();
surf=SDL_GetWindowSurface(win); surf=SDL_GetWindowSurface(win);
drwsurf=SDL_CreateRGBSurfaceWithFormat(0, SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_PIXELFORMAT_RGBA32); 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() { void handleInput() {
static int btn=0; static int btn=0;
static int oldx, oldy; static int oldx, oldy;

View File

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

View File

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

View File

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

View File

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