* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / linux86-0.16.17 / libc / bios / rawio.c
blob2da573b2a53da8efa37fc51404a2159171d5105c
1 /*
2 * rawio.c - plagiarised from ../../bootblocks/trk_buf.c
3 */
5 #ifdef DEBUG
6 #include <stdio.h>
7 #endif
9 #include <bios.h>
10 #include <ctype.h>
11 #include <malloc.h>
12 #include "rawio.h"
14 int rawio_disk_drive = 0;
15 int rawio_disk_spt = 7;
16 int rawio_disk_heads = 2;
17 int rawio_disk_cyls = 0;
19 static int last_drive = 0;
20 static int data_len = 0;
21 static long data_trk1 = 0;
22 static char * data_buf1 = 0;
23 static long data_trk2 = 0;
24 static char * data_buf2 = 0;
26 static long bad_track = -1; /* Track number of last unsuccesful read */
28 static long rawio_get_dpt();
30 void rawio_reset_disk()
32 if( data_buf1 ) free(data_buf1);
33 if( data_buf2 ) free(data_buf2);
34 data_buf1 = data_buf2 = 0;
35 last_drive = rawio_disk_drive;
37 if( !(rawio_disk_drive & 0x80 ) )
39 rawio_disk_spt = 7; /* Defaults for reading Boot area. */
40 rawio_disk_heads = 2;
41 rawio_disk_cyls = 0;
42 #ifdef DEBUG
43 fprintf(stderr, "reset_disk (hard): spt = %d, heads = %d, cyls = %d\n",
44 rawio_disk_spt,
45 rawio_disk_heads,
46 rawio_disk_cyls);
47 #endif
49 #if defined(__MSDOS__) || defined(__STANDALONE__)
50 else
52 /* Hard disk, get parameters from bios */
53 long dpt;
54 int v;
56 rawio_disk_spt = 17; /* Defaults for reading Boot area. */
57 rawio_disk_heads = 1;
58 rawio_disk_cyls = 0;
60 dpt = rawio_get_dpt(rawio_disk_drive);
61 v = ((dpt>>16) & 0xFF);
62 if( v == 0xFF || v <= (rawio_disk_drive&0x7F) ) return; /* Bad dpt */
64 rawio_disk_spt = (dpt & 0x3F); /* Max sector number 1-63 */
65 if( rawio_disk_spt == 0 ) rawio_disk_spt = 64; /* 1-64 ? */
66 rawio_disk_heads = ((dpt>>24) & 0xFF) + 1; /* Head count 1-256 */
67 rawio_disk_cyls = ((dpt>>8) & 0xFF) + ((dpt<<2) & 0x300) + 1;
69 /* Cyls count, unchecked, only needs != 0, if AMI 386 bios can be
70 * upto 4096 cylinder, otherwise BIOS limit is 1024 cyl.
72 #ifdef DEBUG
73 fprintf(stderr, "reset_disk (soft): spt = %d, heads = %d, cyls = %d\n",
74 rawio_disk_spt,
75 rawio_disk_heads,
76 rawio_disk_cyls);
77 #endif
79 #endif
82 int rawio_read_lsector(sectno, buffer)
83 long sectno;
84 char* buffer;
86 int tries = 6;
87 int rv;
89 int phy_s = 1;
90 int phy_h = 0;
91 int phy_c = 0;
93 if( rawio_disk_drive != last_drive ) rawio_reset_disk();
95 if( rawio_disk_spt < 0 || rawio_disk_spt > 63 || rawio_disk_heads < 1 )
97 phy_s = sectno;
98 rawio_reset_disk();
100 #ifdef DEBUG
101 fprintf(stderr, "read_sector(%ld = %d,%d,%d)\n",
102 sectno, phy_c, phy_h, phy_s+1);
103 #endif
105 else
107 phy_s = sectno%rawio_disk_spt;
108 phy_h = sectno/rawio_disk_spt%rawio_disk_heads;
109 phy_c = sectno/rawio_disk_spt/rawio_disk_heads;
111 #ifdef DEBUG
112 fprintf(stderr, "read_sector(%ld = %d,%d,%d)\n",
113 sectno, phy_c, phy_h, phy_s+1);
114 #endif
115 if( rawio_fetch_track_buf(phy_c, phy_h, phy_s) >= 0 )
117 #ifdef DEBUG
118 fprintf(stderr, "read_sector: ftb worked\n");
119 #endif
120 memcpy(buffer, data_buf1 + (phy_s % data_len) * 512, 512);
121 return 512;
125 data_len = -1; /* Zap the cache */
126 if( data_buf1 == 0 )
127 data_buf1 = malloc(512);
128 if( data_buf1 == 0 )
130 #ifdef DEBUG
131 fprintf(stderr, "Cannot allocate memory for disk read!!!\n");
132 #endif
133 return 0;
136 #ifdef DEBUG
137 fprintf(stderr, "WARNING: Single sector read\n");
138 #endif
142 rv = rawio_phy_read(rawio_disk_drive, phy_c, phy_h, phy_s+1, 1, data_buf1);
143 tries--;
144 #ifdef DEBUG
145 if( rv ) fprintf(stderr, "Error in phy_read(%d,%d,%d,%d,%d,%d);\n",
146 rawio_disk_drive, phy_c, phy_h, phy_s+1, 1, data_buf1);
147 #endif
149 while(rv && tries > 0);
151 if(rv)
153 #ifdef DEBUG
154 fprintf(stderr, "rawio failed\n");
155 #endif
156 return 0;
158 else
160 #ifdef DEBUG
161 fprintf(stderr, "rawio worked\n");
162 #endif
163 memcpy(buffer, data_buf1, 512);
164 return 512;
168 rawio_fetch_track_buf(phy_c, phy_h, phy_s)
169 int phy_c, phy_h, phy_s;
171 long trk_no, t;
172 char * p;
173 int tries = 3;
174 int rv, nlen;
176 /* Big tracks get us short of memory so limit it. */
177 nlen = (rawio_disk_spt-1)/22;
178 nlen = (rawio_disk_spt+nlen)/(nlen+1);
179 trk_no = (long)phy_c*rawio_disk_heads*4+phy_h*4+phy_s/nlen+1;
181 if( data_len != nlen )
183 if( data_buf1 ) free(data_buf1);
184 if( data_buf2 ) free(data_buf2);
185 data_buf1 = data_buf2 = 0;
186 data_len = rawio_disk_spt;
188 #ifdef DEBUG
189 fprintf(stderr,
190 "ftb: trk_no=%ld, data_trk1=%ld, data_buf1=%x\n",
191 trk_no,
192 data_trk1,
193 data_buf1);
194 #endif
195 if( trk_no == bad_track ) return -1;
197 if( data_buf1 && trk_no == data_trk1 ) return 0;
199 /* Two cases:
200 * 1) buffer2 has the one we want, need to swap to make it most recent
201 * 2) Neither has it, need to swap to overwrite least recent.
204 /* So we always swap */
205 p = data_buf1; data_buf1 = data_buf2; data_buf2 = p;
206 t = data_trk1; data_trk1 = data_trk2; data_trk2 = t;
208 #ifdef DEBUG
209 fprintf(stderr, "ftb swap: trk_no=%ld, data_trk1=%ld, data_buf1=%x\n",
210 trk_no,
211 data_trk1,
212 data_buf1);
213 #endif
214 /* The other one right ? */
215 if( data_buf1 && trk_no == data_trk1 ) return 0;
217 /* If we get here we have to do a physical read ... */
218 /* into data_buf1. */
220 if( data_buf1 == 0 )
222 data_buf1 = malloc(rawio_disk_spt*512);
224 #ifdef __ELKS__
225 fprintf(stderr, "Allocated buffer to %d\n", data_buf1);
226 #endif
228 if( data_buf1 == 0 )
230 /* Is buf2 allocated ? Yes take it! */
231 data_buf1 = data_buf2; data_buf2 = 0; data_trk2 = -1;
234 bad_track = -1;
235 data_trk1 = -1;
237 #ifdef DEBUG
238 fprintf(stderr, "ftb buf: trk_no=%ld, data_trk1=%ld, data_buf1=%x\n",
239 trk_no,
240 data_trk1,
241 data_buf1);
242 #endif
243 /* Not enough memory for track read. */
244 if( data_buf1 == 0 ) return -1;
246 do /* the physical read */
248 rv = rawio_phy_read(rawio_disk_drive, phy_c, phy_h, phy_s/data_len+1, data_len,
249 data_buf1);
250 tries--;
251 #ifdef DEBUG
252 if( rv ) fprintf(stderr, "Error in phy_read(%d,%d,%d,%d,%d,%d);\n",
253 rawio_disk_drive, phy_c, phy_h, phy_s/data_len+1, data_len, data_buf1);
254 #endif
256 while(rv && tries > 0);
258 /* Disk error, it'll try one at a time, _very_ slowly! */
259 if(rv)
261 bad_track = trk_no;
262 return -1;
265 /* Yes! */
266 data_trk1 = trk_no;
267 return 0;
270 #if defined(__MSDOS__) || defined(__STANDALONE__)
271 rawio_phy_read(drive, cyl, head, sect, length, buffer)
273 #asm
274 push bp
275 mov bp,sp
277 push es
278 push ds
279 pop es
281 mov dl,[bp+2+_rawio_phy_read.drive]
282 mov ch,[bp+2+_rawio_phy_read.cyl]
283 mov dh,[bp+2+_rawio_phy_read.head]
284 mov bx,[bp+2+_rawio_phy_read.buffer]
286 mov ax,[bp+2+_rawio_phy_read.cyl] ! Bits 10-11 of cylinder, AMI BIOS.
287 mov cl,#4
288 sar ax,cl
289 and al,#$C0
290 xor dh,al
292 mov cl,[bp+2+_rawio_phy_read.sect]
293 and cl,#$3F
294 mov ax,[bp+2+_rawio_phy_read.cyl] ! Bits 8-9 of cylinder.
295 sar ax,#1
296 sar ax,#1
297 and al,#$C0
298 or cl,al
300 mov al,[bp+2+_rawio_phy_read.length]
301 mov ah,#$02
302 int $13
303 jc read_err
304 mov ax,#0
305 read_err:
307 pop es
308 pop bp
309 #endasm
312 long
313 rawio_get_dpt(drive)
315 #asm
316 push bp
317 mov bp,sp
319 push di
320 push es
322 mov dl,[bp+2+_rawio_get_dpt.drive]
324 mov ah,#$08
325 int $13
326 jnc func_ok
327 mov cx,ax
328 mov dx,#-1
329 func_ok:
330 mov ax,cx
332 pop es
333 pop di
334 pop bp
335 #endasm
337 #endif