Add rtc; fix via int (hackily). We have got a no disk error now!

This commit is contained in:
Jeroen Domburg 2017-03-04 17:08:03 +08:00
parent 5e88ad2df0
commit 460baa1a7b
7 changed files with 269 additions and 13 deletions

View File

@ -1,8 +1,8 @@
TARGET:=tme
MUSASHI_GEN_SRC:=musashi/m68kops.c musashi/m68kopac.c musashi/m68kopdm.c musashi/m68kopnz.c
OBJ:=$(MUSASHI_GEN_SRC:%.x=%.o) musashi/m68kcpu.o main.o emu.o disp.o iwm.o via.o
OBJ:=$(MUSASHI_GEN_SRC:%.x=%.o) musashi/m68kcpu.o main.o emu.o disp.o iwm.o via.o rtc.o
#musashi/m68kdasm.o
CFLAGS=-Wall -I. -I./musashi -ggdb `sdl2-config --cflags`
CFLAGS=-Wall -I. -I./musashi -Og -ggdb `sdl2-config --cflags`
LDFLAGS=`sdl2-config --libs`
$(TARGET): $(OBJ)

55
emu.c
View File

@ -5,11 +5,13 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include "config.h"
#include "m68k.h"
#include "disp.h"
#include "iwm.h"
#include "via.h"
#include "rtc.h"
unsigned char *macRom;
unsigned char *macRam;
@ -33,7 +35,7 @@ unsigned int m68k_read_memory_8(unsigned int address) {
ret=macRom[romAdr&(TME_ROMSIZE-1)];
// rom_remap=0; //HACK
} else if (address >= 0xE80000 && address < 0xf00000) {
ret=viaRead((address>>8)&0xf);
ret=viaRead((address>>9)&0xf);
} else if (address >= 0xc00000 && address < 0xe00000) {
ret=iwmRead((address>>9)&0xf);
} else {
@ -51,7 +53,7 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) {
} else if (address >= 0x600000 && address < 0xA00000) {
macRam[address & (TME_RAMSIZE-1)]=value;
} else if (address >= 0xE80000 && address < 0xf00000) {
viaWrite((address>>8)&0xf, value);
viaWrite((address>>9)&0xf, value);
} else if (address >= 0xc00000 && address < 0xe00000) {
iwmWrite((address>>9)&0xf, value);
} else {
@ -59,24 +61,58 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) {
}
}
//Should be called every second.
void printFps() {
struct timeval tv;
static struct timeval oldtv;
gettimeofday(&tv, NULL);
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", 100000/msec);
}
oldtv.tv_sec=tv.tv_sec;
oldtv.tv_usec=tv.tv_usec;
}
#define GRAN 100
void tmeStartEmu(void *rom) {
int ca1=0, ca2=0;
int x, frame=0;
macRom=rom;
macRam=malloc(TME_RAMSIZE);
for (int x=0; x<TME_RAMSIZE; x++) macRam[x]=x;
rom_remap=1;
viaClear(VIA_PORTA, 0x7F);
viaSet(VIA_PORTA, 0x80);
m68k_init();
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
m68k_pulse_reset();
dispInit();
while(1) {
m68k_execute(8000000/60);
for (x=0; x<8000000/60; x+=GRAN) {
m68k_execute(GRAN);
viaStep(GRAN);
}
dispDraw(&macRam[video_remap?0x12700:0x1A700]);
// printf("Int!\n");
// m68k_set_irq(2);
frame++;
ca1^=1;
viaControlWrite(VIA_CA1, ca1);
if (frame>=60) {
ca2^=1;
viaControlWrite(VIA_CA2, ca2);
rtcTick();
frame=0;
printFps();
}
}
}
void viaIrq(int req) {
// printf("IRQ %d\n", req);
m68k_set_irq(req?1:0);
}
//Mac uses an 68008, which has an external 16-bit bus. Hence, it should be okay to do everything using 16-bit
//reads/writes.
@ -104,6 +140,12 @@ void m68k_write_memory_16(unsigned int address, unsigned int value) {
m68k_write_memory_8(address+1, value&0xff);
}
void m68k_int_ack(int irq) {
//Mac has level interrupts; no ack. Fake by raising the irq as soon as
//it's serviced.
m68k_set_irq(irq);
}
void viaCbPortAWrite(unsigned int val) {
video_remap=(val&(1<<6))?1:0;
rom_remap=(val&(1<<4))?1:0;
@ -111,5 +153,8 @@ void viaCbPortAWrite(unsigned int val) {
}
void viaCbPortBWrite(unsigned int val) {
int b;
b=rtcCom(val&4, val&1, val&2);
if (b) viaSet(VIA_PORTB, 1); else viaClear(VIA_PORTB, 1);
}

4
m68kconf.h Executable file → Normal file
View File

@ -87,8 +87,8 @@
* If off, all interrupts will be autovectored and all interrupt requests will
* auto-clear when the interrupt is serviced.
*/
#define M68K_EMULATE_INT_ACK OPT_OFF
#define M68K_INT_ACK_CALLBACK(A) your_int_ack_handler_function(A)
#define M68K_EMULATE_INT_ACK OPT_ON
#define M68K_INT_ACK_CALLBACK(A) m68k_int_ack(A)
/* If ON, CPU will call the breakpoint acknowledge callback when it encounters

48
rtc.c Normal file
View File

@ -0,0 +1,48 @@
#include <stdint.h>
#include <stdio.h>
typedef struct {
int lastClkVal;
int pos;
uint8_t cmd;
uint8_t mem[32];
} Rtc;
static Rtc rtc;
void rtcTick() {
int x;
for (x=0; x<3; x++) {
rtc.mem[x]++;
if (rtc.mem[x]!=0) return;
}
}
int rtcCom(int en, int dat, int clk) {
int ret=0;
clk=clk?1:0;
if (en) {
rtc.pos=0;
rtc.cmd=0;
} else {
if (clk!=rtc.lastClkVal && !clk) {
if (rtc.pos<8 || (rtc.pos<16 && ((rtc.cmd&0x8000)==0)) ) {
if (dat) rtc.cmd|=(1<<(15-rtc.pos));
} else if (rtc.cmd&0x8000) {
if (rtc.pos==8) {
rtc.cmd|=rtc.mem[(rtc.cmd&0x7C00)>>10];
}
ret=((rtc.cmd&(1<<(15-rtc.pos)))?1:0);
} else if (rtc.pos==15) {
if ((rtc.cmd&0x8000)==0) rtc.mem[(rtc.cmd&0x7C00)>>10]=rtc.cmd&0xff;
printf("RTC/PRAM CMD %x\n", rtc.cmd);
}
rtc.pos++;
printf("RTC/PRAM pos %d CMD %x\n", rtc.pos, rtc.cmd);
}
}
rtc.lastClkVal=clk;
return ret;
}

2
rtc.h Normal file
View File

@ -0,0 +1,2 @@
void rtcTick();
int rtcCom(int en, int dat, int clk);

156
via.c
View File

@ -5,22 +5,124 @@
void viaCbPortAWrite(unsigned int val);
void viaCbPortBWrite(unsigned int val);
void viaIrq();
#define IFR_IRQ (1<<7)
#define IFR_T1 (1<<6)
#define IFR_T2 (1<<5)
#define IFR_CB1 (1<<4)
#define IFR_CB2 (1<<3)
#define IFR_SR (1<<2)
#define IFR_CA1 (1<<1)
#define IFR_CA2 (1<<0)
#define PCR_NEG 0
#define PCR_NEG_NOCLR 1
#define PCR_POS 2
#define PCR_POS_NOCLR 3
#define PCR_HANDSHAKE 4
#define PCR_PULSEOUT 5
#define PCR_MAN_LO 6
#define PCR_MAN_HI 7
typedef struct {
uint8_t ddra;
uint8_t ddrb;
uint8_t ddra, ddrb;
uint8_t ina, inb;
uint8_t outa, outb;
uint16_t timer1, timer2;
uint16_t latch1, latch2;
uint8_t ifr, ier;
uint8_t pcr, acr;
uint8_t controlin[2];
} Via;
static Via via;
static const char* const viaRegNames[]={
"ORB", "ORA", "DDRB", "DDRA", "T1C-L", "T1C-H", "T1L-L", "T1L-H", "T2L-L",
"T2C-H", "SR", "ACR", "PCR", "IFR", "IER", "ORA-NC"
};
void viaSet(int no, int mask) {
if (no==VIA_PORTA) via.ina|=mask; else via.inb|=mask;
}
void viaClear(int no, int mask) {
if (no==VIA_PORTA) via.ina&=~mask; else via.inb&=~mask;
}
void viaStep(int clockcycles) {
while(clockcycles--) {
if ((via.timer2!=0) || (via.acr&(1<<6))) via.timer2--;
if (via.timer1==0) {
via.ifr|=IFR_T1;
via.timer1=via.latch1;
}
if ((via.timer2!=0) || (via.acr&(1<<5))) via.timer2--;
if (via.timer2==0) {
via.ifr|=IFR_T2;
}
}
}
static void viaCheckIrq() {
static int oldmint=0;
int mint=(via.ifr&via.ier)&0x7F;
if (mint) {
via.ifr|=IFR_IRQ;
viaIrq(1);
// printf("VIA: Raised IRQ because masked if is %x\n", mint);
} else if (!mint) {
if (via.ifr&IFR_IRQ) viaIrq(0);
via.ifr&=~IFR_IRQ;
}
}
static int pcrFor(int no) {
const int shift[]={0, 1, 4, 5};
const int mask[]={1, 3, 1, 3};
int pcr=(via.pcr>>shift[no])&mask[no];
if (no&1) {
if (pcr) return PCR_NEG; else return PCR_POS;
} else {
return pcr;
}
}
static void accessPort(int no) {
via.ifr&=~(no?IFR_CB1:IFR_CA1);
int pcrca2=pcrFor(no?VIA_CB2:VIA_CA2);
if (pcrca2==PCR_NEG || pcrca2==PCR_POS) {
via.ifr&=~(no?IFR_CB2:IFR_CA2);
}
viaCheckIrq();
}
void viaControlWrite(int no, int val) {
const int ifbits[]={IFR_CA1, IFR_CA2, IFR_CB1, IFR_CB2};
int pcr=pcrFor(no);
if (val) val=1;
if (via.controlin[no]!=val) {
if ( ((pcr==PCR_NEG || pcr==PCR_NEG_NOCLR) && !val) ||
((pcr==PCR_POS || pcr==PCR_POS_NOCLR) && val) ) {
via.ifr|=ifbits[no];
viaCheckIrq();
}
}
via.controlin[no]=val;
}
void viaWrite(unsigned int addr, unsigned int val) {
if (addr==0x0) {
//ORB
viaCbPortBWrite(val);
accessPort(1);
} else if (addr==0x1) {
//ORA
viaCbPortAWrite(val);
accessPort(0);
} else if (addr==0x2) {
//DDRB
via.ddrb=val;
@ -29,30 +131,56 @@ void viaWrite(unsigned int addr, unsigned int val) {
via.ddra=val;
} else if (addr==0x4) {
//T1L-L
via.latch1=(via.latch1&0xff00)|val;
} else if (addr==0x5) {
//T1C-H
via.latch1=(via.latch1&0x00ff)|(val<<8);
via.timer1=via.latch1;
via.ifr&=~IFR_T1;
viaCheckIrq();
} else if (addr==0x6) {
//T1L-L
via.latch1=(via.latch1&0xff00)|val;
} else if (addr==0x7) {
//T1L-H
via.latch1=(via.latch1&0x00ff)|(val<<8);
via.ifr&=~IFR_T1;
viaCheckIrq();
} else if (addr==0x8) {
//T2L-l
via.latch2=val;
} else if (addr==0x9) {
//T2C-H
via.timer2=via.latch2|(val<<8);
via.ifr&=~IFR_T2;
viaCheckIrq();
} else if (addr==0xa) {
//SR
printf("6522: Unimplemented: Write %x to SR?\n", val);
} else if (addr==0xb) {
//ACR
via.acr=val;
} else if (addr==0xc) {
//PCR
via.pcr=val;
} else if (addr==0xd) {
//IFR
via.ifr&=~val;
viaCheckIrq();
} else if (addr==0xe) {
//IER
if (val&0x80) {
via.ier|=val;
} else {
via.ier&=~val;
}
via.ier&=0x7f;
viaCheckIrq();
} else if (addr==0xf) {
//ORA
viaCbPortAWrite(val);
}
printf("VIA write %x val %x\n", addr, val);
// printf("VIA write %s val %x\n", viaRegNames[addr], val);
}
@ -61,8 +189,12 @@ unsigned int viaRead(unsigned int addr) {
unsigned int val=0;
if (addr==0x0) {
//ORB
val=via.inb;
accessPort(1);
} else if (addr==0x1) {
//ORA
val=via.ina;
accessPort(0);
} else if (addr==0x2) {
//DDRB
val=via.ddrb;
@ -71,29 +203,45 @@ unsigned int viaRead(unsigned int addr) {
val=via.ddra;
} else if (addr==0x4) {
//T1L-L
val=via.timer1&0xff;
via.ifr&=~IFR_T1;
viaCheckIrq();
} else if (addr==0x5) {
//T1C-H
val=via.timer1>>8;
} else if (addr==0x6) {
//T1L-L
val=via.latch1&0xff;
} else if (addr==0x7) {
//T1L-H
val=via.latch1&0xff;
} else if (addr==0x8) {
//T2L-l
val=via.timer2&0xff;
via.ifr&=~IFR_T2;
viaCheckIrq();
} else if (addr==0x9) {
//T2C-H
val=via.timer2>>8;
} else if (addr==0xa) {
//SR
printf("6522: Unimplemented: Read from SR?\n");
} else if (addr==0xb) {
//ACR
val=via.acr;
} else if (addr==0xc) {
//PCR
val=via.pcr;
} else if (addr==0xd) {
//IFR
val=via.ifr;
} else if (addr==0xe) {
//IER
val=via.ier;
} else if (addr==0xf) {
//ORA
val=via.ina;
}
printf("PC %x VIA read %x val %x\n", pc, addr, val);
// printf("PC %x VIA read %s val %x\n", pc, viaRegNames[addr], val);
return val;
}

13
via.h
View File

@ -1,2 +1,15 @@
#define VIA_CA1 0
#define VIA_CA2 1
#define VIA_CB1 2
#define VIA_CB2 3
#define VIA_PORTA 0
#define VIA_PORTB 1
void viaWrite(unsigned int addr, unsigned int val);
unsigned int viaRead(unsigned int addr);
void viaControlWrite(int no, int val);
void viaStep(int clockcycles);
void viaSet(int no, int mask);
void viaClear(int no, int mask);