From cec9a2763dc179822a8802472fe2e914528ff06e Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Sun, 5 Mar 2017 16:53:33 +0800 Subject: [PATCH] Add HD support. Seems to work but Mac crashes... --- Makefile | 2 +- config.h | 6 +- emu.c | 12 ++- hd.c | 72 ++++++++++++++++ hd.h | 3 + ncr.c | 246 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- ncr.h | 21 +++++ rtc.c | 1 - 8 files changed, 350 insertions(+), 13 deletions(-) create mode 100644 hd.c create mode 100644 hd.h diff --git a/Makefile b/Makefile index 6e95da8..a9ef1d1 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ 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 rtc.o ncr.o +OBJ:=$(MUSASHI_GEN_SRC:%.x=%.o) musashi/m68kcpu.o main.o emu.o disp.o iwm.o via.o rtc.o ncr.o hd.o #musashi/m68kdasm.o CFLAGS=-Wall -I. -I./musashi -Og -ggdb `sdl2-config --cflags` LDFLAGS=`sdl2-config --libs` diff --git a/config.h b/config.h index ccb39b0..e609f90 100644 --- a/config.h +++ b/config.h @@ -2,7 +2,9 @@ #define TME_ROMSIZE (128*1024) -#define TME_RAMSIZE (512*1024) +#define TME_RAMSIZE (4096*1024) #define TME_SCREENBUF (TME_RAMSIZE-0x5900) -#define TME_SCREENBUF_ALT (TME_RAMSIZE-0xd900) +#define TME_SCREENBUF_ALT (TME_RAMSIZE-0xD900) + + diff --git a/emu.c b/emu.c index 25a2539..89906d9 100644 --- a/emu.c +++ b/emu.c @@ -13,6 +13,7 @@ #include "via.h" #include "rtc.h" #include "ncr.h" +#include "hd.h" unsigned char *macRom; unsigned char *macRam; @@ -30,10 +31,13 @@ unsigned int m68k_read_memory_8(unsigned int address) { } } else if (address >= 0x600000 && address < 0xA00000) { ret=macRam[(address-0x600000) & (TME_RAMSIZE-1)]; - } else if (address >= 0x400000 && address<0x41FFFF) { + } else if (address >= 0x400000 && address<0x500000) { int romAdr=address-0x400000; - if (romAdr>=TME_ROMSIZE) printf("PC %x:Huh? Read from ROM mirror (%x)\n", pc, address); - ret=macRom[romAdr&(TME_ROMSIZE-1)]; + if (romAdr>=TME_ROMSIZE) { + printf("PC %x:Huh? Read from ROM mirror (%x)\n", pc, address); + } else { + ret=macRom[romAdr&(TME_ROMSIZE-1)]; + } } else if (address >= 0xE80000 && address < 0xf00000) { ret=viaRead((address>>9)&0xf); } else if (address >= 0xc00000 && address < 0xe00000) { @@ -88,6 +92,8 @@ void tmeStartEmu(void *rom) { macRam=malloc(TME_RAMSIZE); for (int x=0; x +#include +#include +#include +#include "ncr.h" +#include "hd.h" + +typedef struct { + FILE *f; + int size; +} HdPriv; + +const uint8_t inq_resp[95]={ + 0, //HD + 0, //0x80 if removable + 0x49, //Obsolete SCSI standard 1 all the way + 0, //response version etc + 31, //extra data + 0,0, //reserved + 0, //features + 'A','P','P','L','E',' ',' ',' ', //vendor id + '2','0','S','C',' ',' ',' ',' ', //prod id + '1','.','0',' ',' ',' ',' ',' ', //prod rev lvl +}; + +static int hdScsiCmd(SCSITransferData *data, unsigned int cmd, unsigned int len, unsigned int lba, void *arg) { + int ret=0; + HdPriv *hd=(HdPriv*)arg; + 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 + memcpy(data->data, inq_resp, sizeof(inq_resp)); + return 95; + } else if (cmd==0x25) { //read capacity + int lbacnt=hd->size/512; + data->data[0]=(lbacnt>>24); + data->data[1]=(lbacnt>>16); + data->data[2]=(lbacnt>>8); + data->data[3]=(lbacnt>>0); + data->data[4]=0; + data->data[5]=0; + data->data[6]=2; //512 + data->data[7]=0; + ret=8; + } else { + printf("********** hdScsiCmd: unrecognized command %x\n", cmd); + } + data->cmd[0]=0; //status + data->msg[0]=0; + return ret; +} + +SCSIDevice *hdCreate(char *file) { + SCSIDevice *ret=malloc(sizeof(SCSIDevice)); + memset(ret, 0, sizeof(SCSIDevice)); + HdPriv *hd=malloc(sizeof(HdPriv)); + memset(hd, 0, sizeof(HdPriv)); + hd->f=fopen(file, "r+"); + if (hd->f<=0) { + perror(file); + exit(0); + } + hd->size=fseek(hd->f, 0, SEEK_END); + ret->arg=hd; + ret->scsiCmd=hdScsiCmd; + return ret; +} diff --git a/hd.h b/hd.h new file mode 100644 index 0000000..0a70942 --- /dev/null +++ b/hd.h @@ -0,0 +1,3 @@ +#include "ncr.h" + +SCSIDevice *hdCreate(char *file); diff --git a/ncr.c b/ncr.c index d130215..5922b30 100644 --- a/ncr.c +++ b/ncr.c @@ -1,6 +1,7 @@ #include #include - +#include "ncr.h" +#include "m68k.h" static const char* const regNamesR[]={ "CURSCSIDATA","INITIATORCMD", "MODE", "TARGETCMD", "CURSCSISTATUS", @@ -13,15 +14,248 @@ static const char* const regNamesW[]={ }; -unsigned int ncrRead(unsigned int addr, unsigned int dack) { - unsigned int ret=0; +typedef struct { + SCSIDevice *dev[8]; + uint8_t mode; + uint8_t tcr; + uint8_t dout; + uint8_t din; + uint8_t inicmd; + int selected; + int state; + uint8_t tcrforbuf; + SCSITransferData data; + uint8_t *buf; + int bufmax; + int bufpos; + int datalen; +} Ncr; - printf("SCSI: read %s val %x (dack %d)\n", regNamesR[addr], ret, dack); +#define INIR_AIP (1<<6) +#define INIR_LA (1<<5) +#define INI_RST (1<<7) +#define INI_ACK (1<<4) +#define INI_BSY (1<<3) +#define INI_SEL (1<<2) +#define INI_ATN (1<<1) +#define INI_DBUS (1<<0) + +#define SSR_RST (1<<7) +#define SSR_BSY (1<<6) +#define SSR_REQ (1<<5) +#define SSR_MSG (1<<4) +#define SSR_CD (1<<3) +#define SSR_IO (1<<2) +#define SSR_SEL (1<<1) +#define SSR_DBP (1<<0) + +#define TCR_IO (1<<0) +#define TCR_CD (1<<1) +#define TCR_MSG (1<<2) +#define TCR_REQ (1<<3) + +#define MODE_ARB (1<<0) +#define MODE_DMA (1<<1) +#define MODE_MONBSY (1<<2) +#define MODE_EIPINTEN (1<<3) +#define MODE_PARINTEN (1<<4) +#define MODE_PARCHK (1<<5) +#define MODE_TARGET (1<<6) +#define MODE_BDMA (1<<7) + +#define BSR_ACK (1<<0) +#define BSR_ATN (1<<1) +#define BSR_BUSYERR (1<<2) +#define BSR_PHASEMATCH (1<<3) +#define BSR_IRQACT (1<<4) +#define BSR_PARERR (1<<5) +#define BSR_DMARQ (1<<6) +#define BSR_EODMA (1<<7) + +#define ST_IDLE 0 +#define ST_ARB 1 +#define ST_ARBDONE 2 +#define ST_SELECT 3 +#define ST_SELDONE 4 +#define ST_DATA 5 + +static const char* const stateNames[]={ + "IDLE", "ARB", "ARBDONE", "SELECT", "SELDONE", "DATA" +}; + +static Ncr ncr; +static SCSIDevice mydev; + + +static void parseScsiCmd(int isRead) { + uint8_t *buf=ncr.data.cmd; + int cmd=buf[0]; + int lba, len, ctrl; + if (cmd<0x20) { + lba=buf[3]|(buf[2]<<8)|((buf[1]&0x1F)<<16); + len=buf[4]; + ctrl=buf[5]; + } else if (cmd<0x60) { + lba=buf[5]|(buf[4]<<8)|(buf[3]<<16)|(buf[2]<<24); + len=buf[8]|(buf[7]<<8); + ctrl=buf[9]; + } else { + printf("SCSI: UNSUPPORTED CMD %x\n", cmd); + return; + } + 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); + } +} + +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); + } + } + ret=ncr.din; + } 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; + } + } else if (addr==2) { + ret=ncr.mode; + } else if (addr==3) { + ret=ncr.tcr; + } else if (addr==4) { + 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)) { +// ret|=SSR_REQ; + ret|=SSR_BSY; + } + if (ncr.state==ST_DATA) { + if ((ncr.inicmd&INI_ACK)==0) { + ret|=SSR_REQ; + } + } + } else if (addr==5) { + ret=BSR_PHASEMATCH; + if (ncr.mode&MODE_DMA) { + ret|=BSR_DMARQ; + if (ncr.bufpos + +typedef struct { + uint8_t cmd[128]; + uint8_t data[1024*1024]; + uint8_t msg[2]; + int cmdlen; + int datalen; + int msglen; +} SCSITransferData; + +typedef struct { + int (*scsiCmd)(SCSITransferData *data, unsigned int cmd, unsigned int len, unsigned int lba, void *arg); + void *arg; +} SCSIDevice; +void ncrInit(); +void ncrRegisterDevice(int id, SCSIDevice* dev); unsigned int ncrRead(unsigned int addr, unsigned int dack); void ncrWrite(unsigned int addr,unsigned int dack, unsigned int val); + +#endif \ No newline at end of file diff --git a/rtc.c b/rtc.c index 3cc6e70..e723dfe 100644 --- a/rtc.c +++ b/rtc.c @@ -39,7 +39,6 @@ int rtcCom(int en, int dat, int clk) { 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;