diff --git a/emu.c b/emu.c index 89906d9..3349740 100644 --- a/emu.c +++ b/emu.c @@ -20,6 +20,24 @@ unsigned char *macRam; int rom_remap, video_remap=0, audio_remap=0; +void m68k_instruction() { + unsigned int pc=m68k_get_reg(NULL, M68K_REG_PC); + 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"); +} + + unsigned int m68k_read_memory_8(unsigned int address) { unsigned int ret; unsigned int pc=m68k_get_reg(NULL, M68K_REG_PC); @@ -35,6 +53,7 @@ unsigned int m68k_read_memory_8(unsigned int address) { int romAdr=address-0x400000; if (romAdr>=TME_ROMSIZE) { printf("PC %x:Huh? Read from ROM mirror (%x)\n", pc, address); + ret=(address>>12); // ROM checks for same contents at 20000 and 40000 to determine if SCSI is present } else { ret=macRom[romAdr&(TME_ROMSIZE-1)]; } @@ -43,7 +62,7 @@ unsigned int m68k_read_memory_8(unsigned int address) { } else if (address >= 0xc00000 && address < 0xe00000) { ret=iwmRead((address>>9)&0xf); } else if (address >= 0x580000 && address < 0x600000) { - ret=ncrRead((address>>4)&0x7, (address>>7)&1); + ret=ncrRead((address>>4)&0x7, (address>>9)&1); } else { printf("PC %x: Read from %x\n", pc, address); ret=0xff; @@ -54,8 +73,8 @@ unsigned int m68k_read_memory_8(unsigned int address) { void m68k_write_memory_8(unsigned int address, unsigned int value) { unsigned int pc=m68k_get_reg(NULL, M68K_REG_PC); - if (address < 0x400000 && !rom_remap) { - macRam[address & (TME_RAMSIZE-1)]=value; + if (address < 0x400000) { + if (!rom_remap) macRam[address & (TME_RAMSIZE-1)]=value; } else if (address >= 0x600000 && address < 0xA00000) { macRam[(address-0x600000) & (TME_RAMSIZE-1)]=value; } else if (address >= 0xE80000 && address < 0xf00000) { @@ -63,7 +82,7 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) { } else if (address >= 0xc00000 && address < 0xe00000) { iwmWrite((address>>9)&0xf, value); } else if (address >= 0x580000 && address < 0x600000) { - ncrWrite((address>>4)&0x7, (address>>7)&1, value); + ncrWrite((address>>4)&0x7, (address>>9)&1, value); } else { printf("PC %x: Write to %x: %x\n", pc, address, value); } @@ -83,27 +102,28 @@ void printFps() { 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; xcmd[x]); - printf("\n"); +// for (int x=0; x<32; x++) printf("%02X ", data->cmd[x]); +// printf("\n"); if (cmd==0x8 || cmd==0x28) { //read fseek(hd->f, lba*512, SEEK_SET); fread(data->data, 512, len, hd->f); printf("HD: Read %d bytes.\n", len*512); ret=len*512; } else if (cmd==0x12) { //inquiry + printf("HD: Inquery\n"); memcpy(data->data, inq_resp, sizeof(inq_resp)); return 95; } else if (cmd==0x25) { //read capacity @@ -47,6 +48,7 @@ static int hdScsiCmd(SCSITransferData *data, unsigned int cmd, unsigned int len, data->data[6]=2; //512 data->data[7]=0; ret=8; + printf("HD: Read capacity (%d)\n", lbacnt); } else { printf("********** hdScsiCmd: unrecognized command %x\n", cmd); } diff --git a/m68kconf.h b/m68kconf.h index ca39562..e964b91 100644 --- a/m68kconf.h +++ b/m68kconf.h @@ -87,7 +87,7 @@ * 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_ON +#define M68K_EMULATE_INT_ACK OPT_OFF #define M68K_INT_ACK_CALLBACK(A) m68k_int_ack(A) @@ -131,8 +131,8 @@ /* If ON, CPU will call the instruction hook callback before every * instruction. */ -#define M68K_INSTRUCTION_HOOK OPT_OFF -#define M68K_INSTRUCTION_CALLBACK() your_instruction_hook_function() +#define M68K_INSTRUCTION_HOOK OPT_SPECIFY_HANDLER +#define M68K_INSTRUCTION_CALLBACK() m68k_instruction() /* If ON, the CPU will emulate the 4-byte prefetch queue of a real 68000 */ diff --git a/ncr.c b/ncr.c index 5922b30..6a762a8 100644 --- a/ncr.c +++ b/ncr.c @@ -91,19 +91,25 @@ static void parseScsiCmd(int isRead) { uint8_t *buf=ncr.data.cmd; int cmd=buf[0]; int lba, len, ctrl; - if (cmd<0x20) { + int group=(cmd>>5); + if (group==0) { //6-byte command lba=buf[3]|(buf[2]<<8)|((buf[1]&0x1F)<<16); len=buf[4]; + if (len==0) len=256; ctrl=buf[5]; - } else if (cmd<0x60) { + for (int x=0; x<6; x++) printf("%02X ", buf[x]); + printf("\n"); + } else if (group==1 || group==2) { //10-byte command lba=buf[5]|(buf[4]<<8)|(buf[3]<<16)|(buf[2]<<24); len=buf[8]|(buf[7]<<8); ctrl=buf[9]; + for (int x=0; x<10; x++) printf("%02X ", buf[x]); + printf("\n"); } else { printf("SCSI: UNSUPPORTED CMD %x\n", cmd); return; } - printf("SCSI: CMD %x LBA %x LEN %x CTRL %x\n", cmd, lba, len, ctrl); +// printf("SCSI: CMD %x LBA %x LEN %x CTRL %x\n", cmd, lba, len, ctrl); if (ncr.dev[ncr.selected]) { ncr.datalen=ncr.dev[ncr.selected]->scsiCmd(&ncr.data, cmd, len, lba, ncr.dev[ncr.selected]->arg); } @@ -112,21 +118,22 @@ static void parseScsiCmd(int isRead) { unsigned int ncrRead(unsigned int addr, unsigned int dack) { unsigned int pc=m68k_get_reg(NULL, M68K_REG_PC); unsigned int ret=0; - if (addr==0) { - if (ncr.mode&MODE_DMA) { - if (ncr.tcr&TCR_IO) { - if (ncr.bufpos!=ncr.bufmax) ncr.din=ncr.buf[ncr.bufpos++]; -// printf("Send next byte dma %d/%d\n", ncr.bufpos, ncr.datalen); - } + if (ncr.mode&MODE_DMA && dack) { + if (ncr.tcr&TCR_IO) { + if (ncr.bufpos!=ncr.bufmax) ncr.din=ncr.buf[ncr.bufpos++]; +// printf("Send next byte dma %d/%d\n", ncr.bufpos, ncr.datalen); } + } + if (addr==0) { ret=ncr.din; +// printf("READ BYTE %02X dack=%d\n", ret, dack); } else if (addr==1) { // /rst s s /ack /bsy /sel /atn databus ret=ncr.inicmd; if (ncr.state==ST_ARB) { ret|=INIR_AIP; //We don't have a timer... just set arb to be done right now. - ncr.state=ST_ARBDONE; + if (ncr.dev[ncr.selected]) ncr.state=ST_ARBDONE; } } else if (addr==2) { ret=ncr.mode; @@ -136,8 +143,11 @@ unsigned int ncrRead(unsigned int addr, unsigned int dack) { ret=0; if (ncr.inicmd&INI_RST) ret|=SSR_RST; if (ncr.inicmd&INI_BSY) ret|=SSR_BSY; - if (ncr.inicmd&INI_SEL) ret|=SSR_SEL; - if (ncr.dev[ncr.selected] && (ncr.state==ST_SELDONE || ncr.state==ST_DATA)) { +// if (ncr.inicmd&INI_SEL) ret|=SSR_SEL; + if (ncr.tcr&TCR_IO) ret|=SSR_IO; + if (ncr.tcr&TCR_CD) ret|=SSR_CD; + if (ncr.tcr&TCR_MSG) ret|=SSR_MSG; + if (ncr.dev[ncr.selected] && (ncr.state==ST_SELDONE)) { // ret|=SSR_REQ; ret|=SSR_BSY; } @@ -146,22 +156,24 @@ unsigned int ncrRead(unsigned int addr, unsigned int dack) { ret|=SSR_REQ; } } + if (ncr.state==ST_ARB) return 0x40; } else if (addr==5) { ret=BSR_PHASEMATCH; if (ncr.mode&MODE_DMA) { ret|=BSR_DMARQ; - if (ncr.bufpos=ncr.datalen) { printf("End of DMA reached: bufpos %d datalen %d\n", ncr.bufpos, ncr.datalen); ret|=BSR_EODMA; } } } else if (addr==6) { ret=ncr.din; +// printf("READ BYTE (NCR addr6) %02X dack=%d\n", ret, dack); } else if (addr==7) { printf("!UNIMPLEMENTED!\n"); } -// printf("%08X SCSI: read %d (%s) val %x (dack %d), cur st %s\n", pc, addr, regNamesR[addr], ret, dack, stateNames[ncr.state]); +// printf("%08X SCSI: (dack %d), cur st %s read %s (reg %d) = %x \n", +// pc, dack, stateNames[ncr.state], regNamesR[addr], addr, ret); return ret; } @@ -169,16 +181,20 @@ unsigned int ncrRead(unsigned int addr, unsigned int dack) { void ncrWrite(unsigned int addr, unsigned int dack, unsigned int val) { unsigned int pc=m68k_get_reg(NULL, M68K_REG_PC); if (addr==0) { + if (ncr.mode&MODE_DMA && dack) { + printf("UNSUPPORTED: dma write\n"); + } ncr.dout=val; + ncr.din=val; } else if (addr==1) { - if ((val&INI_SEL) && (val&INI_DBUS) && (val&INI_BSY) && ncr.state==ST_ARBDONE) { + if ((val&INI_SEL) && (val&INI_DBUS) && (val&INI_BSY) && (ncr.state==ST_ARBDONE || ncr.state==ST_ARB)) { ncr.state=ST_SELECT; if (ncr.dout==0x81) ncr.selected=0; if (ncr.dout==0x82) ncr.selected=1; if (ncr.dout==0x84) ncr.selected=2; if (ncr.dout==0x88) ncr.selected=3; - if (ncr.dout==0x80) ncr.selected=4; - if (ncr.dout==0x90) ncr.selected=5; + if (ncr.dout==0x90) ncr.selected=4; + if (ncr.dout==0xA0) ncr.selected=5; if (ncr.dout==0xC0) ncr.selected=6; printf("Selected dev: %d (val %x)\n", ncr.selected, ncr.dout); } @@ -212,6 +228,7 @@ void ncrWrite(unsigned int addr, unsigned int dack, unsigned int val) { ncr.inicmd|=val&0x9f; } else if (addr==2) { ncr.mode=val; + if (((val&1)==0) && ncr.state==ST_ARB) ncr.state=ST_IDLE; if (val&1) ncr.state=ST_ARB; } else if (addr==3) { if (ncr.tcr!=(val&0xf)) { @@ -224,6 +241,9 @@ void ncrWrite(unsigned int addr, unsigned int dack, unsigned int val) { //Start of data in phase parseScsiCmd(0); } + if ((ncr.tcr&0x7)==TCR_IO) { + printf("Data Out finished: Host read %d/%d bytes.\n", ncr.bufpos, ncr.datalen); + } ncr.bufpos=0; int type=val&(TCR_MSG|TCR_CD); if (type==0) { @@ -245,7 +265,7 @@ void ncrWrite(unsigned int addr, unsigned int dack, unsigned int val) { } ncr.tcr=val&0xf; } else if (addr==4) { - printf("!UNIMPLEMENTED! selenable, todo\n"); + if (val!=0) printf("!UNIMPLEMENTED! selenable (val %x), todo\n", val); } else if (addr==5) { printf("!UNIMPLEMENTED!\n"); } else if (addr==6) { @@ -253,7 +273,7 @@ void ncrWrite(unsigned int addr, unsigned int dack, unsigned int val) { } else if (addr==7) { //Start DMA. We already do this using the mode bit. } -// printf("%08X SCSI: write %d (%s) val %x (dack %d), cur state %s\n", pc, addr, regNamesW[addr], val, dack, stateNames[ncr.state]); + printf("%08X SCSI: (dack %d), cur state %s %02x to %s (reg %d)\n", pc, dack, stateNames[ncr.state], val, regNamesW[addr], addr); } void ncrRegisterDevice(int id, SCSIDevice* dev){ diff --git a/ncr.h b/ncr.h index b4a7353..e7b4dd4 100644 --- a/ncr.h +++ b/ncr.h @@ -3,9 +3,9 @@ #include typedef struct { - uint8_t cmd[128]; + uint8_t cmd[256]; uint8_t data[1024*1024]; - uint8_t msg[2]; + uint8_t msg[128]; int cmdlen; int datalen; int msglen; diff --git a/via.c b/via.c index 91da3a6..5692939 100644 --- a/via.c +++ b/via.c @@ -55,13 +55,14 @@ void viaClear(int no, int mask) { void viaStep(int clockcycles) { while(clockcycles--) { - if ((via.timer2!=0) || (via.acr&(1<<6))) via.timer2--; - if (via.timer1==0) { + if (via.timer1==1) { via.ifr|=IFR_T1; via.timer1=via.latch1; } - if ((via.timer2!=0) || (via.acr&(1<<5))) via.timer2--; + 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; } }