|
|
1.1 root 1: /*
1.1.1.5 root 2: Hatari - floppy.c
1.1 root 3:
1.1.1.5 root 4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
6:
7: This where we read/write sectors to/from the disc image buffers. NOTE these
8: buffers are in memory so we only need to write routines for the .ST format.
9: When the buffer is to be saved (ie eject disc) we save it back to the original
10: file in the correct format (.ST or .MSA).
11:
12: There are some important notes about image accessing - as we use TOS and the
13: FDC to access the disc the boot-sector MUST be valid. Sometimes this is NOT
14: the case! In these situations we must guess at the disc format. Eg, some disc
15: images have a a boot sector which states single-sided, but the images have
16: been created as double-sided. As sides are interleaved we need to read the
17: image as if it was double-sided. Also note that 'NumBytesPerSector' is ALWAYS
18: 512 bytes, even if the boot-sector states otherwise.
1.1.1.4 root 19: Also note that old versions of the MAKEDISK utility do not set the correct
20: boot sector structure for a real ST (and also Hatari) to read it correctly.
21: (PaCifiST will, however, read/write to these images as it does not perform
22: FDC access as on a real ST)
1.1 root 23: */
1.1.1.6 ! root 24: static char rcsid[] = "Hatari $Id: floppy.c,v 1.12 2003/06/23 18:49:46 thothy Exp $";
1.1 root 25:
1.1.1.4 root 26: #include <SDL_endian.h>
27:
1.1 root 28: #include "main.h"
29: #include "debug.h"
1.1.1.6 ! root 30: #include "configuration.h"
1.1 root 31: #include "errlog.h"
32: #include "file.h"
33: #include "floppy.h"
34: #include "memAlloc.h"
35: #include "memorySnapShot.h"
36: #include "misc.h"
37: #include "msa.h"
38: #include "st.h"
1.1.1.6 ! root 39: #include "zip.h"
1.1 root 40:
41: EMULATION_DRIVE EmulationDrives[NUM_EMULATION_DRIVES]; /* Emulation drive details, eg FileName, Inserted, Changed etc... */
42: int nBootDrive=0; /* Drive A, default */
1.1.1.6 ! root 43: BOOL bFloppyChanged; /* TRUE if a new floppy has been inserted */
1.1 root 44:
45: /* Possible disc image file extensions to scan for */
1.1.1.5 root 46: char *pszDiscImageNameExts[] =
47: {
1.1 root 48: ".msa",
49: ".st",
50: NULL
51: };
52:
53:
1.1.1.2 root 54: /*-----------------------------------------------------------------------*/
1.1 root 55: /*
56: Initialize emulation floppy drives
57: */
58: void Floppy_Init(void)
59: {
60: int i;
61:
62: /* Clear drive structures */
1.1.1.5 root 63: for(i=0; i<NUM_EMULATION_DRIVES; i++)
64: {
1.1 root 65: /* Clear */
66: Memory_Clear(&EmulationDrives[i],sizeof(EMULATION_DRIVE));
67: /* And allocate buffer */
68: EmulationDrives[i].pBuffer = (unsigned char *)Memory_Alloc(DRIVE_BUFFER_BYTES);
69: }
70: }
71:
1.1.1.2 root 72:
73: /*-----------------------------------------------------------------------*/
1.1 root 74: /*
75: UnInitialize drives
76: */
77: void Floppy_UnInit(void)
78: {
79: int i;
80:
1.1.1.2 root 81: /* Free buffers used for emulation drives */
1.1.1.5 root 82: for(i=0; i<NUM_EMULATION_DRIVES; i++)
83: {
1.1 root 84: Memory_Free(EmulationDrives[i].pBuffer);
85: }
86: }
87:
1.1.1.2 root 88:
89: /*-----------------------------------------------------------------------*/
1.1 root 90: /*
91: Save/Restore snapshot of local variables('MemorySnapShot_Store' handles type)
92: */
93: void Floppy_MemorySnapShot_Capture(BOOL bSave)
94: {
95: int i;
96:
1.1.1.2 root 97: /* Save/Restore details */
1.1.1.5 root 98: for(i=0; i<NUM_EMULATION_DRIVES; i++)
99: {
1.1 root 100: MemorySnapShot_Store(EmulationDrives[i].pBuffer,DRIVE_BUFFER_BYTES);
101: MemorySnapShot_Store(EmulationDrives[i].szFileName,sizeof(EmulationDrives[i].szFileName));
102: MemorySnapShot_Store(&EmulationDrives[i].nImageBytes,sizeof(EmulationDrives[i].nImageBytes));
103: MemorySnapShot_Store(&EmulationDrives[i].bDiscInserted,sizeof(EmulationDrives[i].bDiscInserted));
104: MemorySnapShot_Store(&EmulationDrives[i].bMediaChanged,sizeof(EmulationDrives[i].bMediaChanged));
105: MemorySnapShot_Store(&EmulationDrives[i].bContentsChanged,sizeof(EmulationDrives[i].bContentsChanged));
106: MemorySnapShot_Store(&EmulationDrives[i].bOKToSave,sizeof(EmulationDrives[i].bOKToSave));
107: }
108: }
109:
1.1.1.2 root 110:
111: /*-----------------------------------------------------------------------*/
1.1 root 112: /*
113: Find which device to boot from
114: */
115: void Floppy_GetBootDrive(void)
116: {
1.1.1.3 root 117: /* If we've inserted a disc or not enabled boot from hard-drive, boot from the floppy drive */
1.1 root 118: if ( (!ConfigureParams.HardDisc.bBootFromHardDisc) || (EmulationDrives[0].bDiscInserted) )
1.1.1.3 root 119: nBootDrive = 0; /* Drive A */
1.1 root 120: else
1.1.1.3 root 121: nBootDrive = 2; /* Drive C */
1.1 root 122: }
123:
1.1.1.2 root 124:
125: /*-----------------------------------------------------------------------*/
1.1 root 126: /*
127: Test disc image for valid boot-sector
128:
1.1.1.5 root 129: It has been noticed that some discs, eg blank images made by the (current)
130: MakeDisk utility fill in the boot-sector with incorrect information. Such
131: images cannot be read correctly using a real ST, and also Hatari.
132: To try and prevent data loss, we check for this error and flag the drive so
133: the image will not be saved back to the file.
1.1 root 134: */
135: BOOL Floppy_IsBootSectorOK(int Drive)
136: {
1.1.1.5 root 137: char szString[256];
1.1 root 138: unsigned char *pDiscBuffer;
139:
140: /* Does our drive have a disc in? */
1.1.1.5 root 141: if (EmulationDrives[Drive].bDiscInserted)
142: {
1.1 root 143: pDiscBuffer = EmulationDrives[Drive].pBuffer;
1.1.1.5 root 144:
145: /* Check SPC (byte 13) for !=0 value. If is '0', invalid image and Hatari
146: * won't be-able to read (nor will a real ST)! */
1.1 root 147: if (pDiscBuffer[13]!=0)
1.1.1.5 root 148: {
1.1 root 149: return(TRUE); /* Disc sector is OK! */
1.1.1.5 root 150: }
151: else
152: {
153: sprintf(szString, "Disc in drive %c seems to suffer from the Pacifist/Makedisk bug.\n"
154: "If it does not work, please repair the disk first!\n", 'A' + Drive);
155: Main_Message(szString, "Warning");
156: }
1.1 root 157: }
158:
159: return(FALSE); /* Bad sector */
160: }
161:
1.1.1.2 root 162:
163: /*-----------------------------------------------------------------------*/
1.1 root 164: /*
165: Try to create disc B filename, eg 'auto_100a' becomes 'auto_100b'
166: Return TRUE if think we should try!
167: */
168: BOOL Floppy_CreateDiscBFileName(char *pSrcFileName, char *pDestFileName)
169: {
1.1.1.3 root 170: char szDir[256], szName[128], szExt[32];
1.1 root 171:
1.1.1.3 root 172: /* So, first split name into parts */
173: File_splitpath(pSrcFileName, szDir, szName, szExt);
174: /* All OK? */
1.1.1.5 root 175: if (strlen(szName)>0)
176: {
1.1.1.3 root 177: /* Now, did filename end with an 'A' or 'a'? */
1.1.1.5 root 178: if ( (szName[strlen(szName)-1]=='A') || (szName[strlen(szName)-1]=='a') )
179: {
1.1.1.3 root 180: /* Change 'A' to a 'B' */
181: szName[strlen(szName)-1] += 1;
182: /* And re-build name into destination */
183: File_makepath(pDestFileName,szDir,szName,szExt);
184: /* Does file exist? */
1.1 root 185: if (File_Exists(pDestFileName))
1.1.1.3 root 186: return(TRUE); /* Try this */
1.1 root 187: }
188: }
1.1.1.3 root 189:
1.1.1.2 root 190: return(FALSE); /* No, doesn't have disc B */
1.1 root 191: }
192:
1.1.1.2 root 193:
194: /*-----------------------------------------------------------------------*/
1.1 root 195: /*
196: Insert disc into floppy drive
197: The WHOLE image is copied into our drive buffers, and uncompressed if necessary
198: */
199: BOOL Floppy_InsertDiscIntoDrive(int Drive, char *pszFileName)
200: {
1.1.1.6 ! root 201: return(Floppy_ZipInsertDiscIntoDrive(Drive, pszFileName, NULL));
! 202: }
! 203:
! 204: BOOL Floppy_ZipInsertDiscIntoDrive(int Drive, char *pszFileName, char *pszZipPath)
! 205: {
1.1 root 206: char szDiscBFileName[MAX_FILENAME_LENGTH];
207: int nImageBytes=0;
208:
209: /* Eject disc, if one is inserted(don't inform user) */
210: Floppy_EjectDiscFromDrive(Drive,FALSE);
211:
212: /* See if file exists, and if not get correct extension */
1.1.1.3 root 213: if( !File_Exists(pszFileName) )
214: File_FindPossibleExtFileName(pszFileName,pszDiscImageNameExts);
1.1 root 215:
216: /* Is .MSA or .ST image? */
217: if (File_FileNameIsMSA(pszFileName))
218: nImageBytes = MSA_ReadDisc(pszFileName,EmulationDrives[Drive].pBuffer);
219: else if (File_FileNameIsST(pszFileName))
220: nImageBytes = ST_ReadDisc(pszFileName,EmulationDrives[Drive].pBuffer);
1.1.1.6 ! root 221: else if (File_FileNameIsZIP(pszFileName))
! 222: nImageBytes = ZIP_ReadDisc(pszFileName,pszZipPath,EmulationDrives[Drive].pBuffer);
! 223: else if (File_FileNameIsMSAGZ(pszFileName) || File_FileNameIsSTGZ(pszFileName))
! 224: nImageBytes = GZIP_ReadDisc(pszFileName,EmulationDrives[Drive].pBuffer);
! 225:
1.1 root 226: /* Did load OK? */
1.1.1.5 root 227: if (nImageBytes!=0)
228: {
1.1 root 229: /* Store filename and size */
230: strcpy(EmulationDrives[Drive].szFileName,pszFileName);
231: EmulationDrives[Drive].nImageBytes = nImageBytes;
232: /* And set drive states */
233: EmulationDrives[Drive].bDiscInserted = TRUE;
234: EmulationDrives[Drive].bContentsChanged = FALSE;
235: EmulationDrives[Drive].bMediaChanged = TRUE;
236: EmulationDrives[Drive].bOKToSave = Floppy_IsBootSectorOK(Drive);
237: }
238:
239: /* If we insert a disc into Drive A, should be try to put disc 2 into drive B? */
1.1.1.5 root 240: if ( (Drive==0) && (ConfigureParams.DiscImage.bAutoInsertDiscB) )
241: {
1.1 root 242: strcpy(EmulationDrives[1].szFileName,"");
1.1.1.3 root 243: /* Attempt to make up second filename, eg was 'auto_100a' to 'auto_100b' */
1.1.1.5 root 244: if (Floppy_CreateDiscBFileName(pszFileName,szDiscBFileName))
245: {
1.1.1.3 root 246: /* Put image into Drive B, clear out if fails */
1.1 root 247: if (!Floppy_InsertDiscIntoDrive(1,szDiscBFileName))
248: strcpy(EmulationDrives[1].szFileName,"");
249: }
250: }
1.1.1.3 root 251:
1.1.1.6 ! root 252: bFloppyChanged = TRUE;
! 253:
1.1 root 254: /* Return TRUE if loaded OK */
255: if (nImageBytes)
256: return(TRUE);
257: else
258: return(FALSE);
259: }
260:
1.1.1.2 root 261:
262: /*-----------------------------------------------------------------------*/
1.1 root 263: /*
1.1.1.5 root 264: Eject disc from floppy drive, save contents back to PCs hard-drive if has changed
1.1 root 265: */
1.1.1.5 root 266: void Floppy_EjectDiscFromDrive(int Drive, BOOL bInformUser)
1.1 root 267: {
268: char szString[256];
269:
270: /* Does our drive have a disc in? */
1.1.1.5 root 271: if (EmulationDrives[Drive].bDiscInserted)
272: {
1.1 root 273: /* OK, has contents changed? If so, need to save */
1.1.1.5 root 274: if (EmulationDrives[Drive].bContentsChanged)
275: {
1.1 root 276: /* Is OK to save image(if boot-sector is bad, don't allow a save) */
1.1.1.5 root 277: if (EmulationDrives[Drive].bOKToSave)
278: {
1.1 root 279: /* Save as .MSA or .ST image? */
280: if (File_FileNameIsMSA(EmulationDrives[Drive].szFileName))
281: MSA_WriteDisc(EmulationDrives[Drive].szFileName,EmulationDrives[Drive].pBuffer,EmulationDrives[Drive].nImageBytes);
282: else if (File_FileNameIsST(EmulationDrives[Drive].szFileName))
283: ST_WriteDisc(EmulationDrives[Drive].szFileName,EmulationDrives[Drive].pBuffer,EmulationDrives[Drive].nImageBytes);
1.1.1.6 ! root 284: else if (File_FileNameIsZIP(EmulationDrives[Drive].szFileName))
! 285: ZIP_WriteDisc(EmulationDrives[Drive].szFileName,EmulationDrives[Drive].pBuffer,EmulationDrives[Drive].nImageBytes);
! 286: else if (File_FileNameIsMSAGZ(EmulationDrives[Drive].szFileName) ||
! 287: File_FileNameIsSTGZ(EmulationDrives[Drive].szFileName))
! 288: GZIP_WriteDisc(EmulationDrives[Drive].szFileName,EmulationDrives[Drive].pBuffer,EmulationDrives[Drive].nImageBytes);
! 289:
1.1 root 290: }
291: }
292:
293: /* Inform user that disc has been ejected! */
1.1.1.5 root 294: if (bInformUser)
295: {
1.1 root 296: sprintf(szString,"Disc has been removed from Drive '%c'.",'A'+Drive);
1.1.1.5 root 297: Main_Message(szString, PROG_NAME /*,MB_OK | MB_ICONINFORMATION*/);
1.1 root 298: }
299: }
300:
301: /* Drive is now empty */
302: strcpy(EmulationDrives[Drive].szFileName,"");
303: EmulationDrives[Drive].nImageBytes = 0;
304: EmulationDrives[Drive].bDiscInserted = FALSE;
305: EmulationDrives[Drive].bContentsChanged = FALSE;
306: EmulationDrives[Drive].bOKToSave = FALSE;
307: }
308:
1.1.1.2 root 309:
310: /*-----------------------------------------------------------------------*/
1.1 root 311: /*
312: Eject all disc image from floppy drives - call when quit
313: */
314: void Floppy_EjectBothDrives(void)
315: {
316: /* Eject disc images from drives 'A' and 'B' */
317: Floppy_EjectDiscFromDrive(0,FALSE);
318: Floppy_EjectDiscFromDrive(1,FALSE);
319: }
320:
1.1.1.2 root 321:
322: /*-----------------------------------------------------------------------*/
1.1 root 323: /*
1.1.1.4 root 324: Double-check information read from boot-sector as this is sometimes found to
325: be incorrect. The .ST image file should be divisible by the sector size and
326: sectors per track.
327: NOTE - Pass information from boot-sector to this function (if we can't
328: decide we leave it alone).
1.1 root 329: */
1.1.1.4 root 330: static void Floppy_DoubleCheckFormat(long DiscSize, Uint16 *pnSides, Uint16 *pnSectorsPerTrack)
1.1 root 331: {
332: int nSectorsPerTrack;
333: long TotalSectors;
334:
335: /* Now guess at number of sides */
336: if (DiscSize<(500*1024)) /* Is size is >500k assume 2 sides to disc! */
337: *pnSides = 1;
338: else
339: *pnSides = 2;
340:
341: /* And Sectors Per Track(always 512 bytes per sector) */
342: TotalSectors = DiscSize/512; /* # Sectors on disc image */
1.1.1.2 root 343: /* Does this match up with what we've read from boot-sector? */
1.1 root 344: nSectorsPerTrack = *pnSectorsPerTrack;
345: if (nSectorsPerTrack==0) /* Check valid, default to 9 */
346: nSectorsPerTrack = 9;
1.1.1.4 root 347: if ((TotalSectors%nSectorsPerTrack)!=0)
348: {
1.1 root 349: /* No, we have an invalid boot-sector - re-calculate from disc size */
350: if ((TotalSectors%9)==0) /* Work in this order.... */
351: *pnSectorsPerTrack = 9;
352: else if ((TotalSectors%10)==0)
353: *pnSectorsPerTrack = 10;
354: else if ((TotalSectors%11)==0)
355: *pnSectorsPerTrack = 11;
356: else if ((TotalSectors%12)==0)
357: *pnSectorsPerTrack = 12;
358: }
359: /* else unknown, assume boot-sector is correct!!! */
360: }
361:
1.1.1.2 root 362:
363: /*-----------------------------------------------------------------------*/
1.1 root 364: /*
365: Find details of disc image. We need to do this via a function as sometimes the boot-block
366: is not actually correct with the image - some demos/game discs have incorrect bytes in the
367: boot sector and this attempts to find the correct values.
368: */
1.1.1.4 root 369: void Floppy_FindDiscDetails(unsigned char *pBuffer, int nImageBytes,
370: unsigned short int *pnSectorsPerTrack, unsigned short int *pnSides)
1.1 root 371: {
372: unsigned char *pDiscBuffer;
1.1.1.6 ! root 373: Uint16 nSectorsPerTrack, nSides,nsectors;
1.1 root 374:
375: pDiscBuffer = pBuffer;
376: /* First do check to find number of sectors and bytes per sector */
1.1.1.4 root 377: nSectorsPerTrack = SDL_SwapLE16(*(Uint16 *)(pDiscBuffer+24)); /* SPT */
378: nSides = SDL_SwapLE16(*(Uint16 *)(pDiscBuffer+26)); /* SIDE */
1.1.1.6 ! root 379: nsectors = SDL_SwapLE16(*(Uint16 *)(pDiscBuffer+19)); /* total sectors */
1.1.1.4 root 380:
381: /* Now double-check info as boot-sector may contain incorrect information,
382: eg 'Eat.st' demo, or single/double sides */
1.1.1.6 ! root 383: if (nsectors != nImageBytes/512)
! 384: /* Don't be paranoid : if the number of sectors announced is correct, then chances
! 385: are high that the bootsector is correct */
! 386: Floppy_DoubleCheckFormat(nImageBytes, &nSides, &nSectorsPerTrack);
1.1 root 387:
388: /* And set values */
389: if (pnSectorsPerTrack)
390: *pnSectorsPerTrack = nSectorsPerTrack;
391: if (pnSides)
392: *pnSides = nSides;
393: }
394:
1.1.1.2 root 395:
396: /*-----------------------------------------------------------------------*/
1.1 root 397: /*
398: Read sectors from floppy disc image, return TRUE if all OK
399: NOTE Pass -ve as Count to read whole track
400: */
401: BOOL Floppy_ReadSectors(int Drive,char *pBuffer,unsigned short int Sector,unsigned short int Track,unsigned short int Side, short int Count, int *pnSectorsPerTrack)
402: {
403: unsigned char *pDiscBuffer;
404: unsigned short int nSectorsPerTrack,nSides,nBytesPerTrack;
405: long Offset;
406:
1.1.1.5 root 407: if(Track > 85)
408: {
1.1.1.6 ! root 409: fprintf(stderr,"Floppy_ReadSectors: Strange floppy track (%i)!\n", Track);
! 410: return FALSE;
1.1.1.3 root 411: }
412:
1.1.1.2 root 413: /* Do we have a disc in our drive? */
1.1.1.5 root 414: if (EmulationDrives[Drive].bDiscInserted)
415: {
1.1.1.2 root 416: /* Looks good */
1.1.1.3 root 417: /*StatusBar_SetIcon(STATUS_ICON_FLOPPY,ICONSTATE_UPDATE);*/ /* Sorry - no statusbar in Hatari */
1.1 root 418: pDiscBuffer = EmulationDrives[Drive].pBuffer;
419:
1.1.1.2 root 420: /* Find #sides and #sectors per track */
1.1 root 421: Floppy_FindDiscDetails(EmulationDrives[Drive].pBuffer,EmulationDrives[Drive].nImageBytes,&nSectorsPerTrack,&nSides);
422:
1.1.1.2 root 423: /* Need to read whole track? */
1.1 root 424: if (Count<0)
425: Count = nSectorsPerTrack;
1.1.1.2 root 426: /* Write back number of sector per track */
1.1 root 427: if (pnSectorsPerTrack)
428: *pnSectorsPerTrack = nSectorsPerTrack;
429:
1.1.1.2 root 430: /* Debug check as if we read over the end of a track we read into side 2! */
1.1.1.5 root 431: if (Count>nSectorsPerTrack)
432: {
1.1 root 433: ErrLog_File("ERROR Floppy_ReadSectors reading over single track\n");
434: }
435:
1.1.1.2 root 436: /* Seek to sector */
1.1 root 437: nBytesPerTrack = NUMBYTESPERSECTOR*nSectorsPerTrack;
1.1.1.2 root 438: Offset = nBytesPerTrack*Side; /* First seek to side */
439: Offset += (nBytesPerTrack*nSides)*Track; /* Then seek to track */
440: Offset += (NUMBYTESPERSECTOR*(Sector-1)); /* And finally to sector */
1.1.1.6 ! root 441: if (Offset < 0)
! 442: {
! 443: fprintf(stderr,"Floppy_ReadSectors: Offset is negative (%li)!\n", Offset);
! 444: return FALSE;
! 445: }
! 446:
1.1.1.2 root 447: /* Read sectors (usually 512 bytes per sector) */
1.1 root 448: memcpy(pBuffer,pDiscBuffer+Offset,(int)Count*NUMBYTESPERSECTOR);
449:
450: return(TRUE);
451: }
452:
453: return(FALSE);
454: }
455:
1.1.1.2 root 456:
457: /*-----------------------------------------------------------------------*/
1.1 root 458: /*
459: Write sectors from floppy disc image, return TRUE if all OK
460: NOTE Pass -ve as Count to write whole track
461: */
462: BOOL Floppy_WriteSectors(int Drive,char *pBuffer,unsigned short int Sector,unsigned short int Track,unsigned short int Side, short int Count, int *pnSectorsPerTrack)
463: {
464: unsigned char *pDiscBuffer;
465: unsigned short int nSectorsPerTrack,nSides,nBytesPerTrack;
466: long Offset;
467:
1.1.1.2 root 468: /* Do we have a disc in our drive? */
1.1.1.5 root 469: if (EmulationDrives[Drive].bDiscInserted)
470: {
1.1.1.2 root 471: /* Looks good */
1.1.1.3 root 472: /*StatusBar_SetIcon(STATUS_ICON_FLOPPY,ICONSTATE_UPDATE);*/ /* Sorry - no statusbar in Hatari yet */
1.1 root 473: pDiscBuffer = EmulationDrives[Drive].pBuffer;
474:
1.1.1.2 root 475: /* Find #sides and #sectors per track */
1.1 root 476: Floppy_FindDiscDetails(EmulationDrives[Drive].pBuffer,EmulationDrives[Drive].nImageBytes,&nSectorsPerTrack,&nSides);
477:
1.1.1.2 root 478: /* Need to write whole track? */
1.1 root 479: if (Count<0)
480: Count = nSectorsPerTrack;
1.1.1.2 root 481: /* Write back number of sector per track */
1.1 root 482: if (pnSectorsPerTrack)
483: *pnSectorsPerTrack = nSectorsPerTrack;
484:
1.1.1.2 root 485: /* Debug check as if we write over the end of a track we write into side 2! */
1.1.1.5 root 486: if (Count>nSectorsPerTrack)
487: {
1.1 root 488: ErrLog_File("ERROR Floppy_WriteSectors reading over single track\n");
489: }
490:
1.1.1.2 root 491: /* Seek to sector */
1.1 root 492: nBytesPerTrack = NUMBYTESPERSECTOR*nSectorsPerTrack;
1.1.1.2 root 493: Offset = nBytesPerTrack*Side; /* First seek to side */
494: Offset += (nBytesPerTrack*nSides)*Track; /* Then seek to track */
495: Offset += (NUMBYTESPERSECTOR*(Sector-1)); /* And finally to sector */
496: /* Write sectors (usually 512 bytes per sector) */
1.1 root 497: memcpy(pDiscBuffer+Offset,pBuffer,(int)Count*NUMBYTESPERSECTOR);
1.1.1.2 root 498: /* And set 'changed' flag */
1.1 root 499: EmulationDrives[Drive].bContentsChanged = TRUE;
500:
501: return(TRUE);
502: }
503:
504: return(FALSE);
505: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.