|
|
1.1 ! root 1: /* ! 2: * UAE - The Unusable Amiga Emulator ! 3: * ! 4: * disk support v0.0 ! 5: * v0.0: 950312 ! 6: * ! 7: * (c) 1995 Bernd Schmidt ! 8: */ ! 9: ! 10: #include <iostream.h> ! 11: #include <iomanip.h> ! 12: #include <unistd.h> ! 13: #include <stdio.h> ! 14: ! 15: #include "amiga.h" ! 16: #include "disk.h" ! 17: ! 18: static int side, direction, step; ! 19: static UBYTE selected = 15; ! 20: static bool dskready; ! 21: ! 22: class drive { ! 23: FILE *diskfile; ! 24: unsigned int track; ! 25: unsigned int motoroff; ! 26: unsigned int trackoffs,insecpos; ! 27: bool secok; ! 28: UBYTE secbuf[544]; ! 29: UWORD mfmbuf[544]; ! 30: ULONG getseculong(unsigned int offset); ! 31: ULONG getmfmulong(unsigned int offset); ! 32: void readsec(); ! 33: public: ! 34: drive(char *fname=0); ! 35: void eject(); ! 36: void insert(char *fname); ! 37: void step(); ! 38: bool track0() { return track == 0; } ! 39: bool empty() { return diskfile == 0; } ! 40: void motor(int off); ! 41: void GetData(UWORD &,UWORD &); ! 42: }; ! 43: ! 44: drive::drive(char *fname) ! 45: { ! 46: diskfile = 0; ! 47: if (fname != 0) insert(fname); ! 48: track = 0; ! 49: motoroff = 1; ! 50: } ! 51: ! 52: void drive::eject() ! 53: { ! 54: if (diskfile != 0) fclose(diskfile); ! 55: diskfile = 0; ! 56: } ! 57: ! 58: void drive::insert(char *fname) ! 59: { ! 60: diskfile = fopen(fname,"r+"); ! 61: } ! 62: ! 63: void drive::step() ! 64: { ! 65: if (direction) { ! 66: if (track) track--; ! 67: } else { ! 68: if(track<85) track++; ! 69: } ! 70: } ! 71: ! 72: void drive::motor(int off) ! 73: { ! 74: if (motoroff && !off) { trackoffs = 0; insecpos = 0; secok = false; } ! 75: motoroff = off; ! 76: } ! 77: ! 78: ULONG drive::getmfmulong(unsigned int offs) ! 79: { ! 80: return (mfmbuf[offs] << 16) | mfmbuf[offs+1]; ! 81: } ! 82: ! 83: ULONG drive::getseculong(unsigned int offs) ! 84: { ! 85: return (secbuf[offs] << 24) | (secbuf[offs+1] << 16) | (secbuf[offs+2] << 8) ! 86: | (secbuf[offs+3]); ! 87: } ! 88: ! 89: void drive::readsec() ! 90: { ! 91: int i; ! 92: secbuf[0] = secbuf[1] = 0x00; ! 93: secbuf[2] = secbuf[3] = 0xa1; ! 94: secbuf[4] = 0xff; ! 95: secbuf[5] = track*2+side; ! 96: secbuf[6] = trackoffs; ! 97: secbuf[7] = 10-trackoffs; ! 98: for(i=8;i<24;i++) secbuf[i] = 0; ! 99: fseek(diskfile,((track*2+side)*11+trackoffs)*512,SEEK_SET); ! 100: fread(&secbuf[32],sizeof(UBYTE),512,diskfile); ! 101: ! 102: mfmbuf[0] = mfmbuf[1] = 0xaaaa; ! 103: mfmbuf[2] = mfmbuf[3] = 0x4489; ! 104: ULONG deven,dodd; ! 105: deven = getseculong(4); dodd = deven >> 1; ! 106: deven &= 0x55555555; dodd &= 0x55555555; ! 107: mfmbuf[4] = dodd >> 16; mfmbuf[5] = dodd; ! 108: mfmbuf[6] = deven>> 16; mfmbuf[7] = deven; ! 109: for (i=8;i<48;i++) mfmbuf[i] = 0; ! 110: for (i=0;i<512;i+=4){ ! 111: deven = getseculong(i+32); ! 112: dodd = deven >> 1; ! 113: deven &= 0x55555555; dodd &= 0x55555555; ! 114: mfmbuf[(i>>1)+32] = dodd >> 16; mfmbuf[(i>>1)+33] = dodd; ! 115: mfmbuf[(i>>1)+256+32] = deven>> 16; mfmbuf[(i>>1)+256+33] = deven; ! 116: } ! 117: ! 118: ULONG hck=0,dck=0; ! 119: for(i=4;i<24;i+=2) hck += getmfmulong(i); ! 120: deven = dodd = hck; dodd >>= 1; ! 121: mfmbuf[24] = dodd >> 16; mfmbuf[25] = dodd; ! 122: mfmbuf[26] = deven>> 16; mfmbuf[27] = deven; ! 123: for(i=32;i<544;i+=2) dck += getmfmulong(i); ! 124: deven = dodd = dck; dodd >>= 1; ! 125: mfmbuf[28] = dodd >> 16; mfmbuf[29] = dodd; ! 126: mfmbuf[30] = deven>> 16; mfmbuf[31] = deven; ! 127: secok = true; ! 128: } ! 129: ! 130: void drive::GetData(UWORD &mfm,UWORD &byt) ! 131: { ! 132: if (!secok) readsec(); ! 133: mfm = mfmbuf[insecpos]; byt = secbuf[insecpos++]; ! 134: if (insecpos == 544){ ! 135: secok = false; ! 136: if (++trackoffs == 11) trackoffs = 0; ! 137: } ! 138: } ! 139: ! 140: static drive floppy[4]; ! 141: ! 142: void DISK_init() ! 143: { ! 144: floppy[0].insert("wb13.adf"); ! 145: } ! 146: ! 147: void DISK_select(UBYTE data) ! 148: { ! 149: int step_pulse; ! 150: if (selected != ((data >> 3) & 15)) dskready = false; ! 151: selected = (data >> 3) & 15; ! 152: side = (data >> 2) & 1; ! 153: direction = (data >> 1) & 1; ! 154: step_pulse = data & 1; ! 155: if (step != step_pulse) { ! 156: step = step_pulse; ! 157: if (step == 0){ ! 158: for (int dr=0;dr<4;dr++){ ! 159: if (!(selected & (1<<dr))) { ! 160: floppy[dr].step(); ! 161: } ! 162: } ! 163: } ! 164: } ! 165: for (int dr=0;dr<4;dr++){ ! 166: if (!(selected & (1<<dr))) { ! 167: floppy[dr].motor(data >> 7); ! 168: } ! 169: } ! 170: } ! 171: ! 172: UBYTE DISK_status() ! 173: { ! 174: UBYTE st = 0x3c; ! 175: if (dskready) st &= ~0x20; ! 176: dskready = true; ! 177: for (int dr=0;dr<4;dr++){ ! 178: if (!(selected & (1 << dr))) { ! 179: if (floppy[dr].track0()) { st &= ~0x10; } ! 180: if (floppy[dr].empty()) { st &= ~0x4; } ! 181: } ! 182: } ! 183: return st; ! 184: } ! 185: ! 186: void DISK_GetData(UWORD &mfm,UWORD &byt) ! 187: { ! 188: for (int dr=0;dr<4;dr++){ ! 189: if (!(selected & (1<<dr))) { ! 190: floppy[dr].GetData(mfm,byt); ! 191: } ! 192: } ! 193: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.