static char SCCS_ID [] = "@(#)dsk.c 1.2"; /* * Cartridge disk */ #include #include #include #include "../saio.h" #define DSKERR 0x63 /* wrt chk|ill addr|seek inc|nrdy */ #define ADDR_INTLK 0x10 #define WRT_PROT 0x80 #define NRSRW 0x08 #define SEEK 0x42 #define CNTLERR 0xf1 /* overrun|addr comp fail|def trk|data err */ #define CYL_OV 0x10 #define IDLE 0x02 #define READCMD 0x01 #define WRITECMD 0x02 #define STOP 0x48 #define GO 0x50 #define READ_GO 0x70 #define SELCHBSY 0x08 char dskaddr[8] = { 0xc6, 0xc7, 0xd6, 0xd7, 0xe6, 0xe7, 0xf6, 0xf7 }; char dskcntl = 0xb6; char dskselch = 0xf0; dskstrategy(io, func) register struct iob *io; { daddr_t bn; int dn, cn, sn; register selch, cntl, file; register stat; bn = io->i_bn; dn = io->i_unit; cn = bn/24; if ((sn = (bn<<1)%48) >= 24) sn += 32-24; if ((file = io->i_deva) == 0) file = dskaddr[dn]; if ((cntl = io->i_cntl) == 0) cntl = dskcntl; if ((selch = io->i_selch) == 0) selch = dskselch; while (ss(selch) & SELCHBSY) ; while (! (ss(cntl) & IDLE) ) ; while (ss(file) & (ADDR_INTLK | NRSRW)) ; wh(file, cn); oc(file, SEEK); while (! (ss(cntl) & IDLE) ) ; while ((stat = ss(file)) & NRSRW) ; if (stat & (DSKERR)) { printf("disk error: cyl=%d, sector=%d, er=%x, ad=%x\n", cn, sn, stat, file); return(-1); } oc(selch, STOP); wdh(selch, io->i_ma); wdh(selch, io->i_ma + io->i_cc - 1); wh(file, cn); wd(cntl, sn); if (func == READ) { oc(cntl, READCMD); oc(selch, READ_GO); } else { oc(cntl, WRITECMD); oc(selch, GO); } while (ss(selch) & SELCHBSY) ; oc(selch, STOP); while (! ((stat=ss(cntl)) & IDLE) ) ; if (stat & CNTLERR) { printf("disk error: cyl=%d, sector=%d, er=%x, ad=%x\n", cn, sn, stat, cntl); return(-1); } return(io->i_cc); }