/* * check - a program to check out mini-winis * * L.W. Edmondson * Version for 68KCPM * * * mwopen () * mwread () */ #include "boot.h" #define BUFSIZE 512 #define MWCHANNEL ((char *) 0x50) #define tolower(c) (isupper(c) ? ((c) + ('a' - 'A')) : (c)) #define isupper(c) ('A' <= (c) && (c) <= 'Z') #define UCHAR unsigned char #define MWDRIVE 0 #define S128 0 #define S256 1 #define S512 3 #define S1024 7 #define S2048 15 #define MWCOMMAND 0xc0 #define cmd ((struct mwcmd *) MWCOMMAND) /* * Controller commands */ #define READS 0 #define WRITES 1 #define READH 2 #define FORM 3 #define LOAD 4 #define STAT 5 #define HOME 6 /* * Controller constants */ #define HOMDEL 30 /* step pulse delay during home in 100 us */ #define SETTLE 0 /* controller head-settle time */ #define INT 0x80 /* Interrupt enable bit with step delay */ #define RESET 0x54 /* Reset to controller */ #define MWRESET 0xff0054 #define ATTN 0x55 /* Attention to controller */ #define MWSTATE ((char *) 0xff0055) #define PRECOMP 0x80 /* Write precompensation */ #define HIGHCUR 0x40 /* Use high write current */ #define STEPOUT 0x10 /* step out toward track 0 */ #define LCONST 0x30 /* must be set for LOAD constants command */ #define NOTRDY 4 /* bit 2 of sense status */ #define OK 0xff /* operation completed w/o error */ #define MWSUCCESS 0xff /* operation completed w/o error */ #define INTOFF 0 /* turn off completion interrupts */ #define YES 1 #define NO 0 #define KERNEL 0 /* * Controller command structure * (with additions) * See HD-DMA manual */ struct mwcmd { UCHAR seksel; /* out<<4 | drv */ char losteps, histeps; UCHAR hedsel; /* pcmp<<7 | hicur<<6 | (~head&7)<<2 | drv */ char lodma, middma, hidma; char loarg0, hiarg0; UCHAR arg2; UCHAR arg3; UCHAR op; /* op code */ UCHAR stat; /* completion status */ char lolink, midlink, hilink; short curcyl; }; /* * Globals */ /* = { {153, 4, 17, 30, 128, 128}, /* Seagate 5 meg * {306, 4, 17, 2, 128, 128}, /* generic 10 meg * {306, 6, 17, 2, 128, 128}, /* CMI 16 meg * {640, 6, 17, 0, 256, 256}, /* CMI 32 * {512, 8, 17, 0, 512, 512}, /* Quantum * }; */ /* * Reset (initialize) the controller */ static mwreset () { char *p; * (char *) MWRESET = 0; p = MWCHANNEL; *p++ = lobyte(cmd); *p++ = midbyte(cmd); *p++ = hibyte(cmd); cmd->lolink = lobyte(cmd); cmd->midlink= midbyte(cmd); cmd->hilink = hibyte(cmd); } /* * status command - hddma */ mwstat () { cmd->hiarg0 = HOMDEL; cmd->hedsel |= LCONST; cmd->op = LOAD; mwwait (); cmd->losteps = 0; cmd->histeps = 0; cmd->seksel = MWDRIVE; cmd->hedsel = MWDRIVE; cmd->arg2 = SETTLE; cmd->arg3 = S512; cmd->op = STAT; mwwait (); if (cmd->stat == 0) return NO; if (cmd->stat & NOTRDY) return NO; return YES; } static mwhome () { cmd->hiarg0 = HOMDEL; cmd->hedsel |= LCONST; cmd->op = LOAD; mwwait (); cmd->losteps = ~0; cmd->histeps = ~0; cmd->seksel |= STEPOUT; cmd->op = HOME; cmd->curcyl = 0; mwwait (); } mwload () { cmd->hiarg0 = HOMDEL; cmd->hedsel |= LCONST; cmd->op = LOAD; mwwait(); } mwopen () { mwreset (); if (!mwstat ()) return -1; mwhome (); return 0; } /* * read the given triple on the Morrow HDDMA * data goes in secbuf. * * return YES for success * NO for failure */ mwread (c, h, s, a) int c, h, s; char *a; { return mwio (c, h, s, a, READS); } mwwrite (c, h, s, a) int c, h, s; char *a; { return mwio (c, h, s, a, WRITES); } mwio (cyl, head, sector, addr, op) int cyl, head, sector; char *addr; { short d; cmd->seksel = MWDRIVE; d = cyl - cmd->curcyl; if (d < 0) { d = (-d); cmd->seksel |= STEPOUT; } cmd->losteps = lobyte(d); cmd->histeps = midbyte(d); cmd->curcyl = cyl; cmd->hedsel = MWDRIVE | ((~head & 7) << 2) | HIGHCUR; cmd->loarg0 = lobyte(cyl); cmd->hiarg0 = midbyte(cyl); cmd->arg2 = head; cmd->arg3 = sector; cmd->op = op; cmd->lodma = lobyte(addr); cmd->middma = midbyte(addr); cmd->hidma = hibyte(addr); mwwait (); return cmd->stat != MWSUCCESS; /* return 0 on success */ } mwwait () { run (MWSTATE, &cmd->stat); }