SYS.C
上传用户:dcs7469208
上传日期:2010-01-02
资源大小:443k
文件大小:12k
源码类别:

操作系统开发

开发平台:

DOS

  1. /****************************************************************/
  2. /* */
  3. /*       sys.c */
  4. /*       DOS-C */
  5. /* */
  6. /*        sys utility for DOS-C */
  7. /* */
  8. /* Copyright (c) 1991 */
  9. /* Pasquale J. Villani */
  10. /* All Rights Reserved */
  11. /* */
  12. /* This file is part of DOS-C. */
  13. /* */
  14. /* DOS-C is free software; you can redistribute it and/or */
  15. /* modify it under the terms of the GNU General Public License */
  16. /* as published by the Free Software Foundation; either version */
  17. /* 2, or (at your option) any later version. */
  18. /* */
  19. /* DOS-C is distributed in the hope that it will be useful, but */
  20. /* WITHOUT ANY WARRANTY; without even the implied warranty of */
  21. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See */
  22. /* the GNU General Public License for more details. */
  23. /* */
  24. /* You should have received a copy of the GNU General Public */
  25. /* License along with DOS-C; see the file COPYING.  If not, */
  26. /* write to the Free Software Foundation, 675 Mass Ave, */
  27. /* Cambridge, MA 02139, USA. */
  28. /****************************************************************/
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <fcntl.h>
  32. #include <sys/stat.h>
  33. #include <io.h>
  34. #include <dos.h>
  35. #include <ctype.h>
  36. #include <mem.h>
  37. #include "../../hdr/portab.h"
  38. #include "../../hdr/device.h"
  39. BYTE *pgm = "sys";
  40. BOOL fl_reset(VOID);
  41. COUNT fl_rd_status(WORD);
  42. COUNT fl_read(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
  43. COUNT fl_write(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
  44. BOOL fl_verify(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
  45. BOOL fl_format(WORD, BYTE FAR *);
  46. VOID get_boot(COUNT);
  47. VOID put_boot(COUNT);
  48. BOOL check_space(COUNT, BYTE *);
  49. COUNT ltop(WORD *, WORD *, WORD *, COUNT, COUNT, LONG, byteptr);
  50. BOOL copy(COUNT, BYTE *);
  51. BOOL DiskReset(COUNT);
  52. COUNT DiskRead(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
  53. COUNT DiskWrite(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
  54. /* */
  55. /* special word packing prototypes */
  56. /* */
  57. #ifdef NATIVE
  58. # define getlong(vp, lp) (*(LONG *)(lp)=*(LONG *)(vp))
  59. # define getword(vp, wp) (*(WORD *)(wp)=*(WORD *)(vp))
  60. # define getbyte(vp, bp) (*(BYTE *)(bp)=*(BYTE *)(vp))
  61. # define fgetlong(vp, lp) (*(LONG FAR *)(lp)=*(LONG FAR *)(vp))
  62. # define fgetword(vp, wp) (*(WORD FAR *)(wp)=*(WORD FAR *)(vp))
  63. # define fgetbyte(vp, bp) (*(BYTE FAR *)(bp)=*(BYTE FAR *)(vp))
  64. # define fputlong(lp, vp) (*(LONG FAR *)(vp)=*(LONG FAR *)(lp))
  65. # define fputword(wp, vp) (*(WORD FAR *)(vp)=*(WORD FAR *)(wp))
  66. # define fputbyte(bp, vp) (*(BYTE FAR *)(vp)=*(BYTE FAR *)(bp))
  67. #else
  68. VOID getword(VOID *, WORD *);
  69. VOID getbyte(VOID *, BYTE *);
  70. VOID fgetlong(VOID FAR *, LONG FAR *);
  71. VOID fgetword(VOID FAR *, WORD FAR *);
  72. VOID fgetbyte(VOID FAR *, BYTE FAR *);
  73. VOID fputlong(LONG FAR *, VOID FAR *);
  74. VOID fputword(WORD FAR *, VOID FAR *);
  75. VOID fputbyte(BYTE FAR *, VOID FAR *);
  76. #endif
  77. #define SEC_SIZE 512
  78. #define NDEV 4
  79. #define COPY_SIZE 16384
  80. #define NRETRY 5
  81. static struct media_info
  82. {
  83. ULONG mi_size; /* physical sector size */
  84. UWORD mi_heads; /* number of heads (sides) */
  85. UWORD mi_cyls; /* number of cyl/drive */
  86. UWORD mi_sectors; /* number of sectors/cyl */
  87. ULONG mi_offset; /* relative partition offset */
  88. };
  89. union
  90. {
  91. BYTE bytes[2 * SEC_SIZE];
  92. boot boot_sector;
  93. } buffer;
  94. static struct media_info miarray[NDEV] =
  95. {
  96. {720l, 2, 40, 9, 0l},
  97. {720l, 2, 40, 9, 0l},
  98. {720l, 2, 40, 9, 0l},
  99. {720l, 2, 40, 9, 0l}
  100. };
  101. #define PARTOFF 0x1be
  102. #define N_PART 4
  103. static struct
  104. {
  105. BYTE peBootable;
  106. BYTE peBeginHead;
  107. BYTE peBeginSector;
  108. UWORD peBeginCylinder;
  109. BYTE peFileSystem;
  110. BYTE peEndHead;
  111. BYTE peEndSector;
  112. UWORD peEndCylinder;
  113. LONG peStartSector;
  114. LONG peSectors;
  115. } partition[N_PART];
  116. static int DrvMap[4] = {0, 1, 0x80, 0x81};
  117. COUNT drive, active;
  118. UBYTE newboot[SEC_SIZE], oldboot[SEC_SIZE];
  119. #define SBSIZE 51
  120. #define SBOFFSET 11
  121. #define SIZEOF_PARTENT 16
  122. #define FAT12 0x01
  123. #define FAT16SMALL 0x04
  124. #define EXTENDED 0x05
  125. #define FAT16LARGE 0x06
  126. #define N_RETRY 5
  127. COUNT 
  128. get_part (COUNT drive, COUNT idx)
  129. {
  130. REG retry = N_RETRY;
  131. REG BYTE *p = (BYTE *)&buffer.bytes[PARTOFF + (idx * SIZEOF_PARTENT)];
  132. REG ret;
  133. BYTE packed_byte, pb1;
  134. do
  135. {
  136. ret = fl_read((WORD)DrvMap[drive], (WORD)0, (WORD)0, (WORD)1, (WORD)1, (byteptr)&buffer);
  137. } while (ret != 0 && --retry > 0);
  138. if(ret != 0)
  139. return FALSE;
  140. getbyte((VOID *)p, &partition[idx].peBootable);
  141. ++p;
  142. getbyte((VOID *)p, &partition[idx].peBeginHead);
  143. ++p;
  144. getbyte((VOID *)p, &packed_byte);
  145. partition[idx].peBeginSector = packed_byte & 0x3f;
  146. ++p;
  147. getbyte((VOID *)p, &pb1);
  148. ++p;
  149. partition[idx].peBeginCylinder = pb1 + ((0xc0 & packed_byte) << 2);
  150. getbyte((VOID *)p, &partition[idx].peFileSystem);
  151. ++p;
  152. getbyte((VOID *)p, &partition[idx].peEndHead);
  153. ++p;
  154. getbyte((VOID *)p, &packed_byte);
  155. partition[idx].peEndSector = packed_byte & 0x3f;
  156. ++p;
  157. getbyte((VOID *)p, &pb1);
  158. ++p;
  159. partition[idx].peEndCylinder = pb1 + ((0xc0 & packed_byte) << 2);
  160. getlong((VOID *)p, &partition[idx].peStartSector);
  161. p += sizeof(LONG);
  162. getlong((VOID *)p, &partition[idx].peSectors);
  163. return TRUE;
  164. }
  165. VOID main(argc, argv)
  166. COUNT argc;
  167. BYTE *argv[];
  168. {
  169. if(argc != 2)
  170. {
  171. fprintf(stderr, "Useage: %s driven drive = A,B,etc.n", pgm);
  172. exit(1);
  173. }
  174. drive = *argv[1] - (islower(*argv[1]) ? 'a' : 'A');
  175. if(drive < 0 || drive >= NDEV)
  176. {
  177. fprintf(stderr, "%s: drive out of rangen", pgm);
  178. exit(1);
  179. }
  180. if(!DiskReset(drive))
  181. {
  182. fprintf(stderr, "%s: cannot reset drive %c:",
  183. drive, 'A' + drive);
  184. exit(1);
  185. }
  186. get_boot(drive);
  187. if(!check_space(drive, oldboot))
  188. {
  189. fprintf(stderr, "%s: cannot transfer system filesn", pgm);
  190. exit(1);
  191. }
  192. put_boot(drive);
  193. if(!copy(drive, "ipl.sys"))
  194. {
  195. fprintf(stderr, "%s: cannot copy "IPL.SYS"n", pgm);
  196. exit(1);
  197. }
  198. if(!copy(drive, "kernel.exe"))
  199. {
  200. fprintf(stderr, "%s: cannot copy "KERNEL.EXE"n", pgm);
  201. exit(1);
  202. }
  203. if(!copy(drive, "boot.bin"))
  204. {
  205. fprintf(stderr, "%s: cannot copy "BOOT.BIN"n", pgm);
  206. exit(1);
  207. }
  208. if(!copy(drive, "command.com"))
  209. {
  210. fprintf(stderr, "%s: cannot copy "COMMAND.COM"n", pgm);
  211. exit(1);
  212. }
  213. exit(0);
  214. }
  215. VOID put_boot(drive)
  216. COUNT drive;
  217. {
  218. COUNT i;
  219. COUNT ifd;
  220. WORD head, track, sector, ret;
  221. WORD count;
  222. if(drive >= 2)
  223. {
  224. head = partition[active].peBeginHead;
  225. sector = partition[active].peBeginSector;
  226. track = partition[active].peBeginCylinder;
  227. }
  228. else
  229. {
  230. head = 0;
  231. sector = 1;
  232. track = 0;
  233. }
  234. if((ifd = open("boot.bin", O_RDONLY | O_BINARY)) < 0)
  235. {
  236. fprintf(stderr, "%s: can't open"boot.bin"n", pgm);
  237. exit(1);
  238. }
  239. if(read(ifd, newboot, SEC_SIZE) < SEC_SIZE)
  240. {
  241. fprintf(stderr, "%s: error read "boot.bin"", pgm);
  242. exit(1);
  243. }
  244. close(ifd);
  245. if((i = DiskRead(DrvMap[drive], head, track, sector, 1, (BYTE far *)oldboot)) != 0)
  246. {
  247. fprintf(stderr, "%s: disk read error (code = 0x%02x)n", pgm, i & 0xff);
  248. exit(1);
  249. }
  250. memcpy(&newboot[SBOFFSET], &oldboot[SBOFFSET], SBSIZE);
  251. if((i = DiskWrite(DrvMap[drive], head, track, sector, 1, (BYTE far *)newboot)) != 0)
  252. {
  253. fprintf(stderr, "%s: disk write error (code = 0x%02x)n", pgm, i & 0xff);
  254. exit(1);
  255. }
  256. }
  257. VOID get_boot(drive)
  258. COUNT drive;
  259. {
  260. COUNT i;
  261. COUNT ifd;
  262. WORD head, track, sector, ret;
  263. WORD count;
  264. if(drive >= 2)
  265. {
  266. head = partition[active].peBeginHead;
  267. sector = partition[active].peBeginSector;
  268. track = partition[active].peBeginCylinder;
  269. }
  270. else
  271. {
  272. head = 0;
  273. sector = 1;
  274. track = 0;
  275. }
  276. if((i = DiskRead(DrvMap[drive], head, track, sector, 1, (BYTE far *)oldboot)) != 0)
  277. {
  278. fprintf(stderr, "%s: disk read error (code = 0x%02x)n", pgm, i & 0xff);
  279. exit(1);
  280. }
  281. }
  282. BOOL check_space(drive, BlkBuffer)
  283. COUNT drive;
  284. BYTE *BlkBuffer;
  285. {
  286. BYTE *bpbp;
  287. BYTE nfat;
  288. UWORD nfsect;
  289. ULONG hidden, count;
  290. ULONG block;
  291. UBYTE nreserved;
  292. UCOUNT i;
  293. WORD track, head, sector;
  294. UBYTE buffer[SEC_SIZE];
  295. ULONG bpb_huge;
  296. UWORD bpb_nsize;
  297. /* get local information */
  298. getbyte((VOID *)&BlkBuffer[BT_BPB + BPB_NFAT], &nfat);
  299. getword((VOID *)&BlkBuffer[BT_BPB + BPB_NFSECT], &nfsect);
  300. getlong((VOID *)&BlkBuffer[BT_BPB + BPB_HIDDEN], &hidden);
  301. getbyte((VOID *)&BlkBuffer[BT_BPB + BPB_NRESERVED], &nreserved);
  302. getlong((VOID *)&BlkBuffer[BT_BPB + BPB_HUGE], &bpb_huge);
  303. getword((VOID *)&BlkBuffer[BT_BPB + BPB_NSIZE], &bpb_nsize);
  304. count = miarray[drive].mi_size = bpb_nsize == 0 ?
  305.  bpb_huge : bpb_nsize;
  306. /* Fix media information for disk */
  307. getword((&(((BYTE *)&BlkBuffer[BT_BPB])[BPB_NHEADS])), &miarray[drive].mi_heads);
  308. head = miarray[drive].mi_heads;
  309. getword((&(((BYTE *)&BlkBuffer[BT_BPB])[BPB_NSECS])), &miarray[drive].mi_sectors);
  310. if(miarray[drive].mi_size == 0)
  311. getlong(&((((BYTE *)&BlkBuffer[BT_BPB])[BPB_HUGE])), &miarray[drive].mi_size);
  312. sector = miarray[drive].mi_sectors;
  313. if(head == 0 || sector == 0)
  314. {
  315. fprintf(stderr, "Drive initialization failuren");
  316. exit(1);
  317. }
  318. miarray[drive].mi_cyls = count / (head * sector);
  319. return;
  320. }
  321. /* */
  322. /* Do logical block number to physical head/track/sector mapping */
  323. /* */
  324. static COUNT ltop(trackp, sectorp, headp, unit, count, strt_sect, strt_addr)
  325. WORD *trackp, *sectorp, *headp;
  326. REG COUNT unit;
  327. LONG strt_sect;
  328. COUNT count;
  329. byteptr strt_addr;
  330. {
  331. #ifdef I86
  332. ULONG ltemp;
  333. #endif
  334. REG ls, ps;
  335. #ifdef I86
  336. /* Adjust for segmented architecture */
  337. ltemp = (((ULONG)mk_segment(strt_addr) << 4) + mk_offset(strt_addr)) & 0xffff;
  338. /* Test for 64K boundary crossing and return count large */
  339. /* enough not to exceed the threshold. */
  340. count = (((ltemp + SEC_SIZE * count) & 0xffff0000l) != 0l)
  341. ? (0xffffl - ltemp) / SEC_SIZE
  342. : count;
  343. #endif
  344. *trackp = strt_sect / (miarray[unit].mi_heads * miarray[unit].mi_sectors);
  345. *sectorp = strt_sect % miarray[unit].mi_sectors + 1;
  346. *headp = (strt_sect % (miarray[unit].mi_sectors * miarray[unit].mi_heads))
  347. / miarray[unit].mi_sectors;
  348. if(((ls = *headp * miarray[unit].mi_sectors + *sectorp - 1) + count) >
  349. (ps = miarray[unit].mi_heads * miarray[unit].mi_sectors))
  350. count = ps - ls;
  351. return count;
  352. }
  353. BOOL copy(drive, file)
  354. COUNT drive;
  355. BYTE *file;
  356. {
  357. BYTE dest[64];
  358. COUNT ifd, ofd, ret;
  359. BYTE buffer[COPY_SIZE];
  360. struct ftime ftime;
  361. sprintf(dest, "%c:\%s", 'A'+drive, file);
  362. if((ifd = open((BYTE FAR *)file, O_RDONLY | O_BINARY)) < 0)
  363. {
  364. fprintf(stderr, "%s: "%s" not foundn", pgm, file);
  365. return FALSE;
  366. }
  367. _fmode = O_BINARY;
  368. if((ofd = creat((BYTE FAR *)dest, S_IREAD | S_IWRITE)) < 0)
  369. {
  370. fprintf(stderr, "%s: can't create"%s"n", pgm, dest);
  371. return FALSE;
  372. }
  373. while((ret = read(ifd, (VOID *)buffer, COPY_SIZE)) == COPY_SIZE)
  374. write(ofd, (VOID *)buffer, ret);
  375. if(ret >= 0)
  376. write(ofd, (VOID *)buffer, ret);
  377. getftime(ifd, &ftime);
  378. setftime(ofd, &ftime);
  379. close(ifd);
  380. close(ofd);
  381. return TRUE;
  382. }
  383. BOOL DiskReset(COUNT Drive)
  384. {
  385. REG COUNT idx;
  386. /* Reset the drives */
  387. fl_reset();
  388. if(Drive >= 2 && Drive < NDEV)
  389. {
  390. COUNT RetCode;
  391. /* Retrieve all the partition information */
  392. for(RetCode = TRUE, idx = 0; RetCode && (idx < N_PART); idx++)
  393. RetCode = get_part(Drive, idx);
  394. if(!RetCode)
  395. return FALSE;
  396. /* Search for the first DOS partition and start */
  397. /* building the map for the hard drive */
  398. for(idx = 0; idx < N_PART; idx++)
  399. {
  400. if(partition[idx].peFileSystem == FAT12
  401. || partition[idx].peFileSystem == FAT16SMALL
  402. || partition[idx].peFileSystem == FAT16LARGE)
  403. {
  404. miarray[Drive].mi_offset
  405.  = partition[idx].peStartSector;
  406. active = idx;
  407. break;
  408. }
  409. }
  410. }
  411. return TRUE;
  412. }
  413. COUNT DiskRead(WORD drive, WORD head, WORD track, WORD sector, WORD count, BYTE FAR *buffer)
  414. {
  415. int nRetriesLeft;
  416. for(nRetriesLeft = NRETRY; nRetriesLeft > 0; --nRetriesLeft)
  417. {
  418. if(fl_read(drive, head, track, sector, count, buffer) == count)
  419. return count;
  420. }
  421. return 0;
  422. }
  423. COUNT DiskWrite(WORD drive, WORD head, WORD track, WORD sector, WORD count, BYTE FAR *buffer)
  424. {
  425. int nRetriesLeft;
  426. for(nRetriesLeft = NRETRY; nRetriesLeft > 0; --nRetriesLeft)
  427. {
  428. if(fl_write(drive, head, track, sector, count, buffer) == count)
  429. return count;
  430. }
  431. return 0;
  432. }