2017-03-03 07:47:14 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "emu.h"
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
2017-03-04 09:08:03 +00:00
|
|
|
#include <sys/time.h>
|
2017-03-08 12:29:10 +00:00
|
|
|
#include "tmeconfig.h"
|
2017-03-03 07:47:14 +00:00
|
|
|
#include "m68k.h"
|
|
|
|
#include "disp.h"
|
2017-03-03 12:27:22 +00:00
|
|
|
#include "iwm.h"
|
|
|
|
#include "via.h"
|
2017-03-24 10:12:59 +00:00
|
|
|
#include "scc.h"
|
2017-03-04 09:08:03 +00:00
|
|
|
#include "rtc.h"
|
2017-03-04 14:06:00 +00:00
|
|
|
#include "ncr.h"
|
2017-03-05 08:53:33 +00:00
|
|
|
#include "hd.h"
|
2017-03-24 10:12:59 +00:00
|
|
|
#include "mouse.h"
|
2017-03-03 07:47:14 +00:00
|
|
|
|
|
|
|
unsigned char *macRom;
|
|
|
|
unsigned char *macRam;
|
|
|
|
|
2017-03-03 12:27:22 +00:00
|
|
|
int rom_remap, video_remap=0, audio_remap=0;
|
2017-03-03 07:47:14 +00:00
|
|
|
|
2017-03-06 16:06:22 +00:00
|
|
|
void m68k_instruction() {
|
|
|
|
unsigned int pc=m68k_get_reg(NULL, M68K_REG_PC);
|
2017-03-08 12:29:10 +00:00
|
|
|
printf("Mon: %x\n", pc);
|
2017-03-06 16:06:22 +00:00
|
|
|
int ok=0;
|
|
|
|
if (pc < 0x400000) {
|
|
|
|
if (rom_remap) {
|
|
|
|
ok=1;
|
|
|
|
}
|
|
|
|
} else if (pc >= 0x400000 && pc<0x500000) {
|
|
|
|
ok=1;
|
|
|
|
}
|
|
|
|
if (!ok) return;
|
|
|
|
pc&=0x1FFFF;
|
|
|
|
if (pc==0x7DCC) printf("Mon: SCSIReadSectors\n");
|
|
|
|
if (pc==0x7E4C) printf("Mon: SCSIReadSectors exit OK\n");
|
|
|
|
if (pc==0x7E56) printf("Mon: SCSIReadSectors exit FAIL\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-03-03 07:47:14 +00:00
|
|
|
unsigned int m68k_read_memory_8(unsigned int address) {
|
|
|
|
unsigned int ret;
|
|
|
|
unsigned int pc=m68k_get_reg(NULL, M68K_REG_PC);
|
2017-03-03 11:42:48 +00:00
|
|
|
if (address < 0x400000) {
|
|
|
|
if (rom_remap) {
|
|
|
|
ret=macRom[address & (TME_ROMSIZE-1)];
|
|
|
|
} else {
|
|
|
|
ret=macRam[address & (TME_RAMSIZE-1)];
|
|
|
|
}
|
2017-03-24 10:12:59 +00:00
|
|
|
} else if (address >= 0x600000 && address < 0x700000) {
|
2017-03-04 14:06:00 +00:00
|
|
|
ret=macRam[(address-0x600000) & (TME_RAMSIZE-1)];
|
2017-03-05 08:53:33 +00:00
|
|
|
} else if (address >= 0x400000 && address<0x500000) {
|
2017-03-03 07:47:14 +00:00
|
|
|
int romAdr=address-0x400000;
|
2017-03-05 08:53:33 +00:00
|
|
|
if (romAdr>=TME_ROMSIZE) {
|
|
|
|
printf("PC %x:Huh? Read from ROM mirror (%x)\n", pc, address);
|
2017-03-06 16:06:22 +00:00
|
|
|
ret=(address>>12); // ROM checks for same contents at 20000 and 40000 to determine if SCSI is present
|
2017-03-05 08:53:33 +00:00
|
|
|
} else {
|
|
|
|
ret=macRom[romAdr&(TME_ROMSIZE-1)];
|
|
|
|
}
|
2017-03-03 11:42:48 +00:00
|
|
|
} else if (address >= 0xE80000 && address < 0xf00000) {
|
2017-03-04 09:08:03 +00:00
|
|
|
ret=viaRead((address>>9)&0xf);
|
2017-03-03 11:42:48 +00:00
|
|
|
} else if (address >= 0xc00000 && address < 0xe00000) {
|
2017-03-03 12:27:22 +00:00
|
|
|
ret=iwmRead((address>>9)&0xf);
|
2017-03-04 14:06:00 +00:00
|
|
|
} else if (address >= 0x580000 && address < 0x600000) {
|
2017-03-06 16:06:22 +00:00
|
|
|
ret=ncrRead((address>>4)&0x7, (address>>9)&1);
|
2017-03-24 10:12:59 +00:00
|
|
|
} else if (address >= 0x800000 && address < 0xC00000) {
|
|
|
|
ret=sccRead(address);
|
2017-03-03 07:47:14 +00:00
|
|
|
} else {
|
|
|
|
printf("PC %x: Read from %x\n", pc, address);
|
2017-03-04 14:06:00 +00:00
|
|
|
ret=0xff;
|
2017-03-03 07:47:14 +00:00
|
|
|
}
|
|
|
|
// printf("Rd %x = %x\n", address, ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void m68k_write_memory_8(unsigned int address, unsigned int value) {
|
|
|
|
unsigned int pc=m68k_get_reg(NULL, M68K_REG_PC);
|
2017-03-06 16:06:22 +00:00
|
|
|
if (address < 0x400000) {
|
|
|
|
if (!rom_remap) macRam[address & (TME_RAMSIZE-1)]=value;
|
2017-03-03 11:42:48 +00:00
|
|
|
} else if (address >= 0x600000 && address < 0xA00000) {
|
2017-03-04 14:06:00 +00:00
|
|
|
macRam[(address-0x600000) & (TME_RAMSIZE-1)]=value;
|
2017-03-03 11:42:48 +00:00
|
|
|
} else if (address >= 0xE80000 && address < 0xf00000) {
|
2017-03-04 09:08:03 +00:00
|
|
|
viaWrite((address>>9)&0xf, value);
|
2017-03-03 11:42:48 +00:00
|
|
|
} else if (address >= 0xc00000 && address < 0xe00000) {
|
2017-03-03 12:27:22 +00:00
|
|
|
iwmWrite((address>>9)&0xf, value);
|
2017-03-04 14:06:00 +00:00
|
|
|
} else if (address >= 0x580000 && address < 0x600000) {
|
2017-03-06 16:06:22 +00:00
|
|
|
ncrWrite((address>>4)&0x7, (address>>9)&1, value);
|
2017-03-24 10:12:59 +00:00
|
|
|
} else if (address >= 0x800000 && address < 0xC00000) {
|
|
|
|
sccWrite(address, value);
|
2017-05-29 16:40:17 +00:00
|
|
|
// printf("PC %x: Write to %x: %x\n", pc, address, value);
|
2017-03-03 07:47:14 +00:00
|
|
|
} else {
|
|
|
|
printf("PC %x: Write to %x: %x\n", pc, address, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-04 09:08:03 +00:00
|
|
|
//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;
|
2017-03-08 12:29:10 +00:00
|
|
|
printf("Speed: %d%%\n", (int)(100000/msec));
|
2017-03-04 09:08:03 +00:00
|
|
|
}
|
|
|
|
oldtv.tv_sec=tv.tv_sec;
|
|
|
|
oldtv.tv_usec=tv.tv_usec;
|
|
|
|
}
|
|
|
|
|
2017-03-08 12:29:10 +00:00
|
|
|
void tmeStartEmu(void *ram, void *rom) {
|
2017-03-04 09:08:03 +00:00
|
|
|
int ca1=0, ca2=0;
|
2017-03-24 10:12:59 +00:00
|
|
|
int x, m=0, frame=0;
|
2017-03-03 07:47:14 +00:00
|
|
|
macRom=rom;
|
2017-03-08 12:29:10 +00:00
|
|
|
macRam=ram;
|
|
|
|
printf("Clearing ram...\n");
|
2017-03-06 16:06:22 +00:00
|
|
|
for (int x=0; x<TME_RAMSIZE; x++) macRam[x]=0;
|
2017-03-03 07:47:14 +00:00
|
|
|
rom_remap=1;
|
2017-03-08 12:29:10 +00:00
|
|
|
printf("Creating HD and registering it...\n");
|
2017-03-05 08:53:33 +00:00
|
|
|
SCSIDevice *hd=hdCreate("hd.img");
|
|
|
|
ncrRegisterDevice(6, hd);
|
2017-03-08 12:29:10 +00:00
|
|
|
printf("Initializing m68k...\n");
|
2017-03-04 09:08:03 +00:00
|
|
|
viaClear(VIA_PORTA, 0x7F);
|
|
|
|
viaSet(VIA_PORTA, 0x80);
|
2017-03-06 16:06:22 +00:00
|
|
|
viaClear(VIA_PORTA, 0xFF);
|
|
|
|
viaSet(VIA_PORTB, (1<<3));
|
2017-03-08 12:29:10 +00:00
|
|
|
printf("Initializing m68k...\n");
|
2017-03-03 07:47:14 +00:00
|
|
|
m68k_init();
|
2017-03-08 12:29:10 +00:00
|
|
|
printf("Setting CPU type and resetting...");
|
2017-03-03 07:47:14 +00:00
|
|
|
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
|
|
|
|
m68k_pulse_reset();
|
2017-03-08 12:29:10 +00:00
|
|
|
printf("Display init...\n");
|
2017-03-03 07:47:14 +00:00
|
|
|
dispInit();
|
2017-03-08 12:29:10 +00:00
|
|
|
printf("Done! Running.\n");
|
2017-03-03 07:47:14 +00:00
|
|
|
while(1) {
|
2017-03-06 16:06:22 +00:00
|
|
|
for (x=0; x<8000000/60; x+=10) {
|
|
|
|
m68k_execute(10);
|
|
|
|
viaStep(1); //should run at 783.36KHz
|
2017-03-24 10:12:59 +00:00
|
|
|
m++;
|
|
|
|
if (m>=1000) {
|
|
|
|
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;
|
|
|
|
}
|
2017-03-04 09:08:03 +00:00
|
|
|
}
|
2017-03-04 14:06:00 +00:00
|
|
|
dispDraw(&macRam[video_remap?TME_SCREENBUF_ALT:TME_SCREENBUF]);
|
2017-03-04 09:08:03 +00:00
|
|
|
frame++;
|
|
|
|
ca1^=1;
|
|
|
|
viaControlWrite(VIA_CA1, ca1);
|
|
|
|
if (frame>=60) {
|
|
|
|
ca2^=1;
|
|
|
|
viaControlWrite(VIA_CA2, ca2);
|
|
|
|
rtcTick();
|
|
|
|
frame=0;
|
|
|
|
printFps();
|
|
|
|
}
|
2017-03-03 07:47:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-04 09:08:03 +00:00
|
|
|
void viaIrq(int req) {
|
|
|
|
// printf("IRQ %d\n", req);
|
|
|
|
m68k_set_irq(req?1:0);
|
|
|
|
}
|
2017-03-03 07:47:14 +00:00
|
|
|
|
2017-03-24 10:12:59 +00:00
|
|
|
void sccIrq(int req) {
|
|
|
|
// printf("IRQ %d\n", req);
|
|
|
|
m68k_set_irq(req?2:0);
|
|
|
|
}
|
|
|
|
|
2017-03-03 11:42:48 +00:00
|
|
|
//Mac uses an 68008, which has an external 16-bit bus. Hence, it should be okay to do everything using 16-bit
|
2017-03-03 07:47:14 +00:00
|
|
|
//reads/writes.
|
|
|
|
unsigned int m68k_read_memory_32(unsigned int address) {
|
|
|
|
unsigned int ret;
|
|
|
|
ret=m68k_read_memory_16(address)<<16;
|
|
|
|
ret|=m68k_read_memory_16(address+2);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int m68k_read_memory_16(unsigned int address) {
|
|
|
|
unsigned int ret;
|
|
|
|
ret=m68k_read_memory_8(address)<<8;
|
|
|
|
ret|=m68k_read_memory_8(address+1);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void m68k_write_memory_32(unsigned int address, unsigned int value) {
|
|
|
|
m68k_write_memory_16(address, value>>16);
|
|
|
|
m68k_write_memory_16(address+2, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void m68k_write_memory_16(unsigned int address, unsigned int value) {
|
|
|
|
m68k_write_memory_8(address, (value>>8)&0xff);
|
|
|
|
m68k_write_memory_8(address+1, value&0xff);
|
|
|
|
}
|
2017-03-03 12:27:22 +00:00
|
|
|
|
|
|
|
void viaCbPortAWrite(unsigned int val) {
|
2017-03-06 16:06:22 +00:00
|
|
|
int oldRomRemap=rom_remap;
|
2017-03-03 12:27:22 +00:00
|
|
|
video_remap=(val&(1<<6))?1:0;
|
|
|
|
rom_remap=(val&(1<<4))?1:0;
|
|
|
|
audio_remap=(val&(1<<3))?1:0;
|
2017-03-06 16:06:22 +00:00
|
|
|
if (oldRomRemap!=rom_remap) printf("ROM REMAP %d\n", rom_remap);
|
2017-03-23 12:46:17 +00:00
|
|
|
iwmSetHeadSel(val&(1<<5));
|
2017-03-03 12:27:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void viaCbPortBWrite(unsigned int val) {
|
2017-03-04 09:08:03 +00:00
|
|
|
int b;
|
|
|
|
b=rtcCom(val&4, val&1, val&2);
|
|
|
|
if (b) viaSet(VIA_PORTB, 1); else viaClear(VIA_PORTB, 1);
|
2017-03-03 12:27:22 +00:00
|
|
|
}
|
|
|
|
|