|
|
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.