2 * rawio.c - plagiarised from ../../bootblocks/trk_buf.c
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. */
43 fprintf(stderr
, "reset_disk (hard): spt = %d, heads = %d, cyls = %d\n",
49 #if defined(__MSDOS__) || defined(__STANDALONE__)
52 /* Hard disk, get parameters from bios */
56 rawio_disk_spt
= 17; /* Defaults for reading Boot area. */
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.
73 fprintf(stderr
, "reset_disk (soft): spt = %d, heads = %d, cyls = %d\n",
82 int rawio_read_lsector(sectno
, buffer
)
93 if( rawio_disk_drive
!= last_drive
) rawio_reset_disk();
95 if( rawio_disk_spt
< 0 || rawio_disk_spt
> 63 || rawio_disk_heads
< 1 )
101 fprintf(stderr
, "read_sector(%ld = %d,%d,%d)\n",
102 sectno
, phy_c
, phy_h
, phy_s
+1);
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
;
112 fprintf(stderr
, "read_sector(%ld = %d,%d,%d)\n",
113 sectno
, phy_c
, phy_h
, phy_s
+1);
115 if( rawio_fetch_track_buf(phy_c
, phy_h
, phy_s
) >= 0 )
118 fprintf(stderr
, "read_sector: ftb worked\n");
120 memcpy(buffer
, data_buf1
+ (phy_s
% data_len
) * 512, 512);
125 data_len
= -1; /* Zap the cache */
127 data_buf1
= malloc(512);
131 fprintf(stderr
, "Cannot allocate memory for disk read!!!\n");
137 fprintf(stderr
, "WARNING: Single sector read\n");
142 rv
= rawio_phy_read(rawio_disk_drive
, phy_c
, phy_h
, phy_s
+1, 1, data_buf1
);
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
);
149 while(rv
&& tries
> 0);
154 fprintf(stderr
, "rawio failed\n");
161 fprintf(stderr
, "rawio worked\n");
163 memcpy(buffer
, data_buf1
, 512);
168 rawio_fetch_track_buf(phy_c
, phy_h
, phy_s
)
169 int phy_c
, phy_h
, phy_s
;
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
;
190 "ftb: trk_no=%ld, data_trk1=%ld, data_buf1=%x\n",
195 if( trk_no
== bad_track
) return -1;
197 if( data_buf1
&& trk_no
== data_trk1
) return 0;
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
;
209 fprintf(stderr
, "ftb swap: trk_no=%ld, data_trk1=%ld, data_buf1=%x\n",
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. */
222 data_buf1
= malloc(rawio_disk_spt
*512);
225 fprintf(stderr
, "Allocated buffer to %d\n", data_buf1
);
230 /* Is buf2 allocated ? Yes take it! */
231 data_buf1
= data_buf2
; data_buf2
= 0; data_trk2
= -1;
238 fprintf(stderr
, "ftb buf: trk_no=%ld, data_trk1=%ld, data_buf1=%x\n",
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
,
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
);
256 while(rv
&& tries
> 0);
258 /* Disk error, it'll try one at a time, _very_ slowly! */
270 #if defined(__MSDOS__) || defined(__STANDALONE__)
271 rawio_phy_read(drive
, cyl
, head
, sect
, length
, buffer
)
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
.
292 mov cl
,[bp
+2+_rawio_phy_read
.sect
]
294 mov ax
,[bp
+2+_rawio_phy_read
.cyl
] ! Bits
8-9 of cylinder
.
300 mov al
,[bp
+2+_rawio_phy_read
.length
]
322 mov dl
,[bp
+2+_rawio_get_dpt
.drive
]