/* * check - a program to check out mini-winis * * L.W. Edmondson * Version for 68KCPM * * * mwopen () * mwread () */ #include "boot.h" #define BUFSIZE 512 #define CHANNEL 0x50 #define tolower(c) (isupper(c) ? ((c) + ('a' - 'A')) : (c)) #define isupper(c) ('A' <= (c) && (c) <= 'Z') #define UINT /* unsigned */ int #define UCHAR /* unsigned */ char #define MWDRIVE 0 #define S128 0 #define S256 1 #define S512 3 #define S1024 7 #define S2048 15 /* * 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 ATTN 0x55 /* Attention to controller */ #define MWSTATE 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 BUSY 0 /* controller is busy */ #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 cmd { 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; }; /* * Globals */ static UINT curcyl = 0, /* current cylinder */ errors = 0, secsize = S512, nbad = 0; /* = { {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 * }; */ static struct cmd cmd = {0}; /* * Reset (initialize) the controller */ static reset () { char *p; out(RESET, 0); p = CHANNEL; *p++ = lobyte(&cmd); *p++ = midbyte(&cmd); *p = 0; 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 = secsize; 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; curcyl = 0; mwwait (); } mwload () { cmd.hiarg0 = HOMDEL; cmd.hedsel |= LCONST; cmd.op = LOAD; mwwait(); } /* * Select a new drive */ mwinit () { if (!mwstat ()) return NO; mwhome (); mwload (); return YES; } /* * read the given triple on the Morrow HDDMA * data goes in secbuf. * * return YES for success * NO for failure */ mwread (cyl, head, sector, addr) int cyl, head, sector; char *addr; { short d; cmd.seksel = MWDRIVE; d = cyl - curcyl; if (d < 0) { d = (-d); cmd.seksel |= STEPOUT; } cmd.losteps = lobyte(d); cmd.histeps = midbyte(d); 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 = READS; 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); }