|
|
1.1 ! root 1: /* ! 2: Hatari ! 3: ! 4: Floppy Disc Controller(FDC) emulation. We need to simulate the movement of the head of the ! 5: floppy disc drive to accurately perform the FDC commands, such as 'Step'. The is important ! 6: for ST demo disc images. We have to go into a lot of details - including the start up/stop ! 7: of the drive motor. ! 8: To help with this emulation, we keep our own internal commands which are checked each HBL ! 9: to perform the transfer of data from our disc image into the ST RAM area by simulating the ! 10: DMA. ! 11: */ ! 12: ! 13: #include "main.h" ! 14: #include "debug.h" ! 15: #include "decode.h" ! 16: #include "dialog.h" ! 17: #include "fdc.h" ! 18: #include "floppy.h" ! 19: #include "ikbd.h" ! 20: #include "m68000.h" ! 21: #include "memorySnapShot.h" ! 22: #include "mfp.h" ! 23: #include "misc.h" ! 24: #include "psg.h" ! 25: #include "stMemory.h" ! 26: ! 27: /* ! 28: Floppy Disc Controller ! 29: ! 30: Programmable Sound Generator (YM-2149) ! 31: ! 32: 0xff8800(even byte) - PSG Register Data (Read, used for parallel port) ! 33: - PSG Register Select (Write) ! 34: ! 35: Write to bits 0-3 to select PSG register to use(then write data to 0xfff8802) ! 36: Value Register ! 37: ! 38: 0000 Channel A Fine Tune ! 39: 0001 Channel A Coarse Tune ! 40: 0010 Channel B Fine Tune ! 41: 0011 Channel B Coarse Tune ! 42: 0100 Channel C Fine Tune ! 43: 0101 Channel C Coarse Tune ! 44: 0110 Noise Generator Control ! 45: 0111 Mixer Control - I/O enable ! 46: 1000 Channel A Amplitude ! 47: 1001 Channel B Amplitude ! 48: 1010 Channel C Amplitude ! 49: 1011 Envelope Period Fine Tune ! 50: 1100 Envelope Peroid Coarse Tune ! 51: 1101 Envelope Shape ! 52: 1110 I/O Port A Select (Write only) ! 53: 1111 I/O Port B Select ! 54: ! 55: 0xfff8802(even byte) - Bits according to 0xff8800 Register select ! 56: ! 57: 1110(Register 14) - I/O Port A ! 58: Bit 0 - Floppy side 0/1 ! 59: Bit 1 - Floppy drive 0 select ! 60: Bit 2 - Floppy drive 1 select ! 61: Bit 3 - RS232 Ready to send (RTS) ! 62: Bit 4 - RS232 Data Terminal Ready (DTR) ! 63: Bit 5 - Centronics Strobe ! 64: Bit 6 - General Purpose Output ! 65: Bit 7 - Reserved ! 66: ! 67: ACSI DMA and Floppy Disc Controller(FDC) ! 68: 0xff8604 - information from file '1772.info.txt, by David Gahris' (register r0) ! 69: (write) - Disk controller ! 70: (read) - Disk controller status ! 71: Bit 0 - Busy. This bit is 1 when the 177x is busy. This bit is 0 when the 177x is free for CPU commands. ! 72: Bit 1 - Index / Data Request. On Type I commands, this bit is high during the index pulse that occurs once ! 73: per disk rotation. This bit is low at all times other than the index pulse. For Type II and III commands, ! 74: Bit 1 high signals the CPU to handle the data register in order to maintain a continuous flow of data. ! 75: Bit 1 is high when the data register is full during a read or when the data register is empty during a write. ! 76: "Worst case service time" for Data Request is 23.5 cycles. ! 77: Bit 2 - Track Zero / Lost Data. After Type I commands, this bit is 0 if the mechanism is at track zero. ! 78: This bit is 1 if the head is not at track zero. After Type II or III commands, this bit is 1 if the ! 79: CPU did not respond to Data Request (Status bit 1) in time for the 177x to maintain a continuous data flow. ! 80: This bit is 0 if the CPU responded promptly to Data Request. ! 81: Bit 3 - CRC Error. This bit is high if a sector CRC on disk does not match the CRC which the 177x ! 82: computed from the data. The CRC polynomial is x^16+x^12+x^5+1. If the stored CRC matches the newly ! 83: calculated CRC, the CRC Error bit is low. If this bit and the Record Not Found bit are set, the error ! 84: was in an ID field. If this bit is set but Record Not Found is clear, the error was in a data field. ! 85: Bit 4 - Record Not Found. This bit is set if the 177x cannot find the track, sector, or side which ! 86: the CPU requested. Otherwise, this bit is clear. ! 87: Bit 5 - Spin-up / Record Type. For Type I commands, this bit is low during the 6-revolution motor ! 88: spin-up time. This bit is high after spin-up. For Type II and Type III commands, Bit 5 low ! 89: indicates a normal data mark. Bit 5 high indicates a deleted data mark. ! 90: Bit 6 - Write Protect. This bit is not used during reads. During writes, this bit is high when the disk is write protected. ! 91: Bit 7 - Motor On. This bit is high when the drive motor is on, and low when the motor is off. ! 92: ! 93: 0xff8606 - DMA Status(read), DMA Mode Control(write) - NOTE bits 0,9-15 are not used ! 94: Bit 1 - FDC Pin A0 (See below) ! 95: Bit 2 - FDC Pin A1 ! 96: Bit 3 - FDC/HDC Register Select ! 97: Bit 4 - FDC/Sector count select ! 98: Bit 5 - Reserved ! 99: Bit 6 - Enable/Disable DMA ! 100: Bit 7 - HDC/FDC ! 101: Bit 8 - Read/Write ! 102: ! 103: A1 A0 Read Write(bit 8==1) ! 104: 0 0 Status Command ! 105: 0 1 Track Register Track Register ! 106: 1 0 Sector Register Sector Register ! 107: 1 1 Data Register Data Register ! 108: ! 109: ! 110: This handles any read/writes to the FDC and PSG. FDC commands are then sent through to read/write ! 111: disc sector code. We have full documents on 1772 FDC, but they use r0,r1,r2,r3 etc.. which are ! 112: not seen at first glance as Atari access them via the A0,A1 bits. Once this is understood it ! 113: is all relativly easy as a lot of information can be ignored as we are using disc images and ! 114: not actual discs. We do NOT support the reading of the PC's A: drive - newer PC's cannot read ! 115: an ST single sided disc, ST discs are very old and so are dirty which gets onto the PC drive heads ! 116: and ruins them and also support for disc sector access under Windows is... well not well documented! ! 117: ! 118: According to the documentation INTRQ is generated at the completion of each command(causes an interrupt ! 119: in the MFP). INTRQ is reset by reading the status register OR by loading a new command. So, does this ! 120: mean the GPIP? Or does it actually CANCEL the interrupt? Can this be done? ! 121: */ ! 122: ! 123: #define ENABLE_FLOPPY_SAVING /* Save to floppies */ ! 124: ! 125: unsigned short int DiscControllerStatus_ff8604rd; /* 0xff8604 (read) */ ! 126: unsigned short int DiscControllerWord_ff8604wr; /* 0xff8604 (write) */ ! 127: unsigned short int DMAStatus_ff8606rd; /* 0xff8606 (read) */ ! 128: unsigned short int DMAModeControl_ff8606wr,DMAModeControl_ff8606wr_prev; /* 0xff8606 (write,store prev for 'toggle' checks) */ ! 129: ! 130: unsigned short int FDCCommandRegister; ! 131: short int FDCTrackRegister,FDCSectorRegister,FDCDataRegister; ! 132: short int FDCSectorCountRegister; ! 133: int FDCEmulationCommand; /* FDC emulation command currently being exceuted */ ! 134: int FDCEmulationRunning; /* Running command under above */ ! 135: int FDCStepDirection; /* +Track on 'Step' command */ ! 136: short int DiscControllerByte; /* Used to pass parameter back to assembler */ ! 137: BOOL bDMAWaiting; /* Is DMA waiting to copy? */ ! 138: int bMotorOn; /* Is motor on? */ ! 139: int MotorSlowingCount; /* Counter used to slow motor before stopping */ ! 140: ! 141: short int nReadWriteTrack; /* Parameters used in sector read/writes */ ! 142: short int nReadWriteSector; ! 143: short int nReadWriteSide; ! 144: short int nReadWriteDev; ! 145: unsigned short int nReadWriteSectorsPerTrack; ! 146: short int nReadWriteSectors; ! 147: ! 148: unsigned char DMASectorWorkSpace[NUMBYTESPERSECTOR]; /* Workspace used to copy to/from for floppy DMA */ ! 149: ! 150: //----------------------------------------------------------------------- ! 151: /* ! 152: Reset variables used in FDC ! 153: */ ! 154: void FDC_Reset(void) ! 155: { ! 156: // Clear out FDC registers ! 157: DiscControllerStatus_ff8604rd = 0; ! 158: DiscControllerWord_ff8604wr = 0; ! 159: DMAStatus_ff8606rd = 0x01; ! 160: DMAModeControl_ff8606wr = DMAModeControl_ff8606wr_prev = 0; ! 161: FDC_ResetDMAStatus(); ! 162: FDCCommandRegister = 0; ! 163: FDCTrackRegister = 0; ! 164: FDCSectorRegister = 1; ! 165: FDCDataRegister = 0; ! 166: FDCSectorCountRegister = 0; ! 167: ! 168: FDCEmulationCommand = FDCEMU_CMD_NULL; /* FDC emulation command currently being exceuted */ ! 169: FDCEmulationRunning = FDCEMU_RUN_NULL; /* Running command under above */ ! 170: ! 171: FDCStepDirection = 1; /* +Track on 'Step' command */ ! 172: bDMAWaiting = FALSE; /* No DMA waiting */ ! 173: bMotorOn = FALSE; /* Motor off */ ! 174: MotorSlowingCount = 0; /* Counter for motor slowing down before stopping */ ! 175: } ! 176: ! 177: //----------------------------------------------------------------------- ! 178: /* ! 179: Save/Restore snapshot of local variables('MemorySnapShot_Store' handles type) ! 180: */ ! 181: void FDC_MemorySnapShot_Capture(BOOL bSave) ! 182: { ! 183: // Save/Restore details ! 184: MemorySnapShot_Store(&DiscControllerStatus_ff8604rd,sizeof(DiscControllerStatus_ff8604rd)); ! 185: MemorySnapShot_Store(&DiscControllerWord_ff8604wr,sizeof(DiscControllerWord_ff8604wr)); ! 186: MemorySnapShot_Store(&DMAStatus_ff8606rd,sizeof(DMAStatus_ff8606rd)); ! 187: MemorySnapShot_Store(&DMAModeControl_ff8606wr,sizeof(DMAModeControl_ff8606wr)); ! 188: MemorySnapShot_Store(&DMAModeControl_ff8606wr_prev,sizeof(DMAModeControl_ff8606wr_prev)); ! 189: MemorySnapShot_Store(&FDCCommandRegister,sizeof(FDCCommandRegister)); ! 190: MemorySnapShot_Store(&FDCTrackRegister,sizeof(FDCTrackRegister)); ! 191: MemorySnapShot_Store(&FDCSectorRegister,sizeof(FDCSectorRegister)); ! 192: MemorySnapShot_Store(&FDCDataRegister,sizeof(FDCDataRegister)); ! 193: MemorySnapShot_Store(&FDCSectorCountRegister,sizeof(FDCSectorCountRegister)); ! 194: MemorySnapShot_Store(&FDCEmulationCommand,sizeof(FDCEmulationCommand)); ! 195: MemorySnapShot_Store(&FDCEmulationRunning,sizeof(FDCEmulationRunning)); ! 196: MemorySnapShot_Store(&FDCStepDirection,sizeof(FDCStepDirection)); ! 197: MemorySnapShot_Store(&DiscControllerByte,sizeof(DiscControllerByte)); ! 198: MemorySnapShot_Store(&bDMAWaiting,sizeof(bDMAWaiting)); ! 199: MemorySnapShot_Store(&bMotorOn,sizeof(bMotorOn)); ! 200: MemorySnapShot_Store(&MotorSlowingCount,sizeof(MotorSlowingCount)); ! 201: MemorySnapShot_Store(&nReadWriteTrack,sizeof(nReadWriteTrack)); ! 202: MemorySnapShot_Store(&nReadWriteSector,sizeof(nReadWriteSector)); ! 203: MemorySnapShot_Store(&nReadWriteSide,sizeof(nReadWriteSide)); ! 204: MemorySnapShot_Store(&nReadWriteDev,sizeof(nReadWriteDev)); ! 205: MemorySnapShot_Store(&nReadWriteSectorsPerTrack,sizeof(nReadWriteSectorsPerTrack)); ! 206: MemorySnapShot_Store(&nReadWriteSectors,sizeof(nReadWriteSectors)); ! 207: MemorySnapShot_Store(DMASectorWorkSpace,sizeof(DMASectorWorkSpace)); ! 208: } ! 209: ! 210: //----------------------------------------------------------------------- ! 211: /* ! 212: Turn floppy motor on ! 213: */ ! 214: void FDC_TurnMotorOn(void) ! 215: { ! 216: bMotorOn = TRUE; /* Turn motor on */ ! 217: MotorSlowingCount = 0; ! 218: } ! 219: ! 220: //----------------------------------------------------------------------- ! 221: /* ! 222: Turn floppy motor off(this sets a count as it takes a set amount of time for the motor to slow to a halt) ! 223: */ ! 224: void FDC_TurnMotorOff(void) ! 225: { ! 226: MotorSlowingCount = 10; /* Set timer so takes 'x' HBLs before turn off... */ ! 227: } ! 228: ! 229: //----------------------------------------------------------------------- ! 230: /* ! 231: Update floppy drive motor each HBL, to simulate slowing down and stopping for drive; needed for New Zealand Story(PP_001) ! 232: */ ! 233: void FDC_UpdateMotor(void) ! 234: { ! 235: // Is drive slowing down? Decrement counter ! 236: if (MotorSlowingCount>0) { ! 237: MotorSlowingCount--; ! 238: ! 239: if (MotorSlowingCount==0) ! 240: bMotorOn = FALSE; /* Motor finally stopped */ ! 241: } ! 242: } ! 243: ! 244: //----------------------------------------------------------------------- ! 245: /* ! 246: Reset DMA Status (RD 0xff8606) ! 247: ! 248: This is done by 'toggling' bit 8 of the DMA Mode Control register ! 249: */ ! 250: void FDC_ResetDMAStatus(void) ! 251: { ! 252: DMAStatus_ff8606rd = 0; /* Clear out */ ! 253: ! 254: FDCSectorCountRegister = 0; ! 255: FDC_SetDMAStatus(FALSE); /* Set no error */ ! 256: } ! 257: ! 258: //----------------------------------------------------------------------- ! 259: /* ! 260: Set DMA Status (RD 0xff8606) ! 261: ! 262: NOTE FDC Doc's are incorrect - Bit 0 is '0' on error (See TOS floprd, Ninja III etc...) ! 263: Look like Atari(yet again) connected the hardware up differently to the spec' ! 264: ! 265: Bit 0 - _Error Status (0=Error) ! 266: Bit 1 - _Sector Count Zero Status (0=Sector Count Zero) ! 267: Bit 2 - _Data Request Inactive Status ! 268: */ ! 269: void FDC_SetDMAStatus(BOOL bError) ! 270: { ! 271: DMAStatus_ff8606rd &= 0x1; /* Clear(except for error) */ ! 272: ! 273: // Set error condition - NOTE this is incorrect in the FDC Doc's! ! 274: if (!bError) ! 275: DMAStatus_ff8606rd |= 0x1; ! 276: ! 277: // Set zero sector count ! 278: if (FDCSectorCountRegister!=0) ! 279: DMAStatus_ff8606rd |= 0x2; ! 280: } ! 281: ! 282: //----------------------------------------------------------------------- ! 283: /* ! 284: Read DMA Status (RD 0xff8606) ! 285: */ ! 286: long FDC_ReadDMAStatus(void) ! 287: { ! 288: return (0xffff0000|DMAStatus_ff8606rd); ! 289: } ! 290: ! 291: //----------------------------------------------------------------------- ! 292: /* ! 293: */ ! 294: void FDC_UpdateDiscDrive(void) ! 295: { ! 296: /* Set details for current selecte drive */ ! 297: nReadWriteDev = FDC_FindFloppyDrive(); ! 298: ! 299: if (EmulationDrives[nReadWriteDev].bDiscInserted) ! 300: Floppy_FindDiscDetails(EmulationDrives[nReadWriteDev].pBuffer,EmulationDrives[nReadWriteDev].nImageBytes,&nReadWriteSectorsPerTrack,NULL); ! 301: } ! 302: ! 303: //----------------------------------------------------------------------- ! 304: /* ! 305: When write to 0xff8606 (DMA Mode Control) check bit '8' toggle. This causes DMA status reset ! 306: */ ! 307: void FDC_CheckForDMAStatusReset(void) ! 308: { ! 309: /* Test for 'toggle' of _read/_write bit '8' */ ! 310: if ((DMAModeControl_ff8606wr_prev ^ DMAModeControl_ff8606wr)&0x0100) ! 311: FDC_ResetDMAStatus(); ! 312: } ! 313: ! 314: //----------------------------------------------------------------------- ! 315: /* ! 316: Set disc controller status (RD 0xff8604) ! 317: */ ! 318: void FDC_SetDiscControllerStatus(void) ! 319: { ! 320: /* Update disc */ ! 321: FDC_UpdateDiscDrive(); ! 322: ! 323: /* Clear out to default */ ! 324: DiscControllerStatus_ff8604rd = 0; ! 325: ! 326: /* ONLY do this if we are running a Type I command */ ! 327: if ((FDCCommandRegister&0x80)==0) { /* Type I - Restore,Seek,Step,Step-In,Step-Out */ ! 328: if (FDCTrackRegister==0) ! 329: DiscControllerStatus_ff8604rd |= 0x4; /* Bit 2 - Track Zero, '0' if head is NOT at zero */ ! 330: } ! 331: ! 332: /* If no disc inserted, tag as error */ ! 333: if (!EmulationDrives[nReadWriteDev].bDiscInserted) ! 334: DiscControllerStatus_ff8604rd |= 0x10; /* RNF - Record not found, ie no disc in drive */ ! 335: } ! 336: ! 337: //----------------------------------------------------------------------- ! 338: /* ! 339: Return device for FDC, check PORTA bits 1,2(0=on,1=off) ! 340: */ ! 341: int FDC_FindFloppyDrive(void) ! 342: { ! 343: /* Check Drive A first */ ! 344: if ((PSGRegisters[PSG_REG_IO_PORTA]&0x2)==0) ! 345: return(0); // Device 0 (A:) ! 346: /* If off, check Drive B */ ! 347: if ((PSGRegisters[PSG_REG_IO_PORTA]&0x4)==0) ! 348: return(1); // Device 1 (B:) ! 349: ! 350: /* None appear to be selected so default to Drive A */ ! 351: return(0); // Device 0 (A:) ! 352: } ! 353: ! 354: //----------------------------------------------------------------------- ! 355: /* ! 356: Acknowledge FDC interrupt ! 357: */ ! 358: void FDC_AcknowledgeInterrupt(void) ! 359: { ! 360: // Acknowledge in MFP circuit, pass bit,enable,pending ! 361: MFP_InputOnChannel(MFP_FDCHDC_BIT,MFP_IERB,&MFP_IPRB); ! 362: MFP_GPIP &= ~0x20; ! 363: } ! 364: ! 365: //----------------------------------------------------------------------- ! 366: /* ! 367: Copy parameters for disc sector/s read/write ! 368: */ ! 369: void FDC_SetReadWriteParameters(int nSectors) ! 370: { ! 371: // Copy read/write details so we can modify them ! 372: nReadWriteTrack = FDCTrackRegister; ! 373: nReadWriteSector = FDCSectorRegister; ! 374: nReadWriteSide = (~PSGRegisters[PSG_REG_IO_PORTA]) & 0x01; ! 375: nReadWriteSectors = nSectors; ! 376: // Update disc ! 377: FDC_UpdateDiscDrive(); ! 378: } ! 379: ! 380: //----------------------------------------------------------------------- ! 381: /* ! 382: Update floppy drive on each HBL(approx' 512 cycles) ! 383: */ ! 384: void FDC_UpdateHBL(void) ! 385: { ! 386: // Do we have a DMA ready to copy? ! 387: if (bDMAWaiting) { ! 388: // Yes, copy it ! 389: FDC_DMADataFromFloppy(); ! 390: // Signal done ! 391: bDMAWaiting = FALSE; ! 392: } ! 393: ! 394: // Update drive motor ! 395: FDC_UpdateMotor(); ! 396: ! 397: // Is FDC active? ! 398: if (FDCEmulationCommand!=FDCEMU_CMD_NULL) { ! 399: // Which command are we running? ! 400: switch(FDCEmulationCommand) { ! 401: case FDCEMU_CMD_RESTORE: ! 402: FDC_UpdateRestoreCmd(); ! 403: break; ! 404: case FDCEMU_CMD_SEEK: ! 405: FDC_UpdateSeekCmd(); ! 406: break; ! 407: case FDCEMU_CMD_STEP: ! 408: FDC_UpdateStepCmd(); ! 409: break; ! 410: case FDCEMU_CMD_STEPIN: ! 411: FDC_UpdateStepInCmd(); ! 412: break; ! 413: case FDCEMU_CMD_STEPOUT: ! 414: FDC_UpdateStepOutCmd(); ! 415: break; ! 416: ! 417: case FDCEMU_CMD_READSECTORS: ! 418: case FDCEMU_CMD_READMULTIPLESECTORS: ! 419: FDC_UpdateReadSectorsCmd(); ! 420: break; ! 421: case FDCEMU_CMD_WRITESECTORS: ! 422: case FDCEMU_CMD_WRITEMULTIPLESECTORS: ! 423: FDC_UpdateWriteSectorsCmd(); ! 424: break; ! 425: } ! 426: ! 427: // Set disc controller status(RD 0xff8604) ! 428: FDC_SetDiscControllerStatus(); ! 429: } ! 430: } ! 431: ! 432: //----------------------------------------------------------------------- ! 433: /* ! 434: Run 'RESTORE' command ! 435: */ ! 436: void FDC_UpdateRestoreCmd(void) ! 437: { ! 438: // Which command is running? ! 439: switch (FDCEmulationRunning) { ! 440: case FDCEMU_RUN_RESTORE_SEEKTOTRACKZERO: ! 441: // Are we at track zero? ! 442: if (FDCTrackRegister>0) ! 443: FDCTrackRegister--; /* Move towards track zero */ ! 444: else { ! 445: FDCTrackRegister = 0; /* We're there */ ! 446: FDCEmulationRunning = FDCEMU_RUN_RESTORE_COMPLETE; ! 447: } ! 448: break; ! 449: case FDCEMU_RUN_RESTORE_COMPLETE: ! 450: // Acknowledge interrupt, move along there's nothing more to see ! 451: FDC_AcknowledgeInterrupt(); ! 452: // Set error ! 453: FDC_SetDMAStatus(FALSE); /* No DMA error */ ! 454: // Done ! 455: FDCEmulationCommand = FDCEMU_CMD_NULL; ! 456: // Turn motor off ! 457: FDC_TurnMotorOff(); ! 458: break; ! 459: } ! 460: } ! 461: ! 462: //----------------------------------------------------------------------- ! 463: /* ! 464: Run 'SEEK' command ! 465: */ ! 466: void FDC_UpdateSeekCmd(void) ! 467: { ! 468: // Which command is running? ! 469: switch (FDCEmulationRunning) { ! 470: case FDCEMU_RUN_SEEK_TOTRACK: ! 471: // Are we at the selected track? ! 472: if (FDCTrackRegister==FDCDataRegister) ! 473: FDCEmulationRunning = FDCEMU_RUN_SEEK_COMPLETE; ! 474: else { ! 475: // No, seek towards track ! 476: if (FDCDataRegister<FDCTrackRegister) ! 477: FDCTrackRegister--; ! 478: else ! 479: FDCTrackRegister++; ! 480: } ! 481: break; ! 482: case FDCEMU_RUN_SEEK_COMPLETE: ! 483: // Acknowledge interrupt, move along there's nothing more to see ! 484: FDC_AcknowledgeInterrupt(); ! 485: // Set error ! 486: FDC_SetDMAStatus(FALSE); // No DMA error ! 487: // Done ! 488: FDCEmulationCommand = FDCEMU_CMD_NULL; ! 489: // Turn motor off ! 490: FDC_TurnMotorOff(); ! 491: break; ! 492: } ! 493: } ! 494: ! 495: //----------------------------------------------------------------------- ! 496: /* ! 497: Run 'STEP' command ! 498: */ ! 499: void FDC_UpdateStepCmd(void) ! 500: { ! 501: // Which command is running? ! 502: switch (FDCEmulationRunning) { ! 503: case FDCEMU_RUN_STEP_ONCE: ! 504: // Move head by one track in same direction as last step ! 505: FDCTrackRegister += FDCStepDirection; ! 506: if (FDCTrackRegister<0) /* Limit to stop */ ! 507: FDCTrackRegister = 0; ! 508: ! 509: FDCEmulationRunning = FDCEMU_RUN_STEP_COMPLETE; ! 510: break; ! 511: case FDCEMU_RUN_STEP_COMPLETE: ! 512: // Acknowledge interrupt, move along there's nothing more to see ! 513: FDC_AcknowledgeInterrupt(); ! 514: // Set error ! 515: FDC_SetDMAStatus(FALSE); /* No DMA error */ ! 516: // Done ! 517: FDCEmulationCommand = FDCEMU_CMD_NULL; ! 518: // Turn motor off ! 519: FDC_TurnMotorOff(); ! 520: break; ! 521: } ! 522: } ! 523: ! 524: //----------------------------------------------------------------------- ! 525: /* ! 526: Run 'STEP IN' command ! 527: */ ! 528: void FDC_UpdateStepInCmd(void) ! 529: { ! 530: // Which command is running? ! 531: switch (FDCEmulationRunning) { ! 532: case FDCEMU_RUN_STEPIN_ONCE: ! 533: FDCTrackRegister++; ! 534: ! 535: FDCEmulationRunning = FDCEMU_RUN_STEPIN_COMPLETE; ! 536: break; ! 537: case FDCEMU_RUN_STEPIN_COMPLETE: ! 538: // Acknowledge interrupt, move along there's nothing more to see ! 539: FDC_AcknowledgeInterrupt(); ! 540: // Set error ! 541: FDC_SetDMAStatus(FALSE); /* No DMA error */ ! 542: // Done ! 543: FDCEmulationCommand = FDCEMU_CMD_NULL; ! 544: // Turn motor off ! 545: FDC_TurnMotorOff(); ! 546: break; ! 547: } ! 548: } ! 549: ! 550: //----------------------------------------------------------------------- ! 551: /* ! 552: Run 'STEP OUT' command ! 553: */ ! 554: void FDC_UpdateStepOutCmd(void) ! 555: { ! 556: // Which command is running? ! 557: switch (FDCEmulationRunning) { ! 558: case FDCEMU_RUN_STEPOUT_ONCE: ! 559: FDCTrackRegister--; ! 560: if (FDCTrackRegister<0) // Limit to stop ! 561: FDCTrackRegister = 0; ! 562: ! 563: FDCEmulationRunning = FDCEMU_RUN_STEPOUT_COMPLETE; ! 564: break; ! 565: case FDCEMU_RUN_STEPOUT_COMPLETE: ! 566: // Acknowledge interrupt, move along there's nothing more to see ! 567: FDC_AcknowledgeInterrupt(); ! 568: // Set error ! 569: FDC_SetDMAStatus(FALSE); // No DMA error ! 570: // Done ! 571: FDCEmulationCommand = FDCEMU_CMD_NULL; ! 572: // Turn motor off ! 573: FDC_TurnMotorOff(); ! 574: break; ! 575: } ! 576: } ! 577: ! 578: //----------------------------------------------------------------------- ! 579: /* ! 580: Run 'READ SECTOR/S' command ! 581: */ ! 582: void FDC_UpdateReadSectorsCmd(void) ! 583: { ! 584: // Which command is running? ! 585: switch (FDCEmulationRunning) { ! 586: case FDCEMU_RUN_READSECTORS_READDATA: ! 587: // Read in a sector ! 588: if (FDC_ReadSectorFromFloppy()) { /* Read a single sector through DMA */ ! 589: FDCSectorCountRegister--; /* Decrement FDCSectorCount */ ! 590: if (FDCSectorCountRegister<=0) ! 591: FDCSectorCountRegister = 0; ! 592: ! 593: // Have we finished? ! 594: nReadWriteSectors--; ! 595: if (nReadWriteSectors<=0) ! 596: FDCEmulationRunning = FDCEMU_RUN_READSECTORS_COMPLETE; ! 597: ! 598: bDMAWaiting = TRUE; ! 599: } ! 600: else { ! 601: // Acknowledge interrupt, move along there's nothing more to see ! 602: FDC_AcknowledgeInterrupt(); ! 603: // Set error ! 604: FDC_SetDMAStatus(TRUE); /* DMA error */ ! 605: // Done ! 606: FDCEmulationCommand = FDCEMU_CMD_NULL; ! 607: // Turn motor off ! 608: FDC_TurnMotorOff(); ! 609: } ! 610: break; ! 611: case FDCEMU_RUN_READSECTORS_COMPLETE: ! 612: // Acknowledge interrupt, move along there's nothing more to see ! 613: FDC_AcknowledgeInterrupt(); ! 614: // Set error ! 615: FDC_SetDMAStatus(FALSE); /* No DMA error */ ! 616: // Done ! 617: FDCEmulationCommand = FDCEMU_CMD_NULL; ! 618: // Turn motor off ! 619: FDC_TurnMotorOff(); ! 620: break; ! 621: } ! 622: } ! 623: ! 624: //----------------------------------------------------------------------- ! 625: /* ! 626: Run 'WRITE SECTOR/S' command ! 627: */ ! 628: void FDC_UpdateWriteSectorsCmd(void) ! 629: { ! 630: // Which command is running? ! 631: switch (FDCEmulationRunning) { ! 632: case FDCEMU_RUN_WRITESECTORS_WRITEDATA: ! 633: // Write out a sector ! 634: if (FDC_WriteSectorFromFloppy()) { /* Write a single sector through DMA */ ! 635: // Decrement FDCsector count ! 636: FDCSectorCountRegister--; /* Decrement FDCSectorCount */ ! 637: if (FDCSectorCountRegister<=0) ! 638: FDCSectorCountRegister = 0; ! 639: ! 640: // Have we finished? ! 641: nReadWriteSectors--; ! 642: if (nReadWriteSectors<=0) ! 643: FDCEmulationRunning = FDCEMU_RUN_WRITESECTORS_COMPLETE; ! 644: ! 645: // Update DMA pointer ! 646: FDC_WriteDMAAddress(FDC_ReadDMAAddress()+NUMBYTESPERSECTOR); ! 647: } ! 648: else { ! 649: // Acknowledge interrupt, move along there's nothing more to see ! 650: FDC_AcknowledgeInterrupt(); ! 651: // Set error ! 652: FDC_SetDMAStatus(TRUE); /* DMA error */ ! 653: // Done ! 654: FDCEmulationCommand = FDCEMU_CMD_NULL; ! 655: // Turn motor off ! 656: FDC_TurnMotorOff(); ! 657: } ! 658: break; ! 659: case FDCEMU_RUN_WRITESECTORS_COMPLETE: ! 660: // Acknowledge interrupt, move along there's nothing more to see ! 661: FDC_AcknowledgeInterrupt(); ! 662: // Set error ! 663: FDC_SetDMAStatus(FALSE); /* No DMA error */ ! 664: // Done ! 665: FDCEmulationCommand = FDCEMU_CMD_NULL; ! 666: // Turn motor off ! 667: FDC_TurnMotorOff(); ! 668: break; ! 669: } ! 670: } ! 671: ! 672: //----------------------------------------------------------------------- ! 673: /* ! 674: Type I Commands ! 675: ! 676: Restore, Seek, Step, Step-In and Step-Out ! 677: */ ! 678: ! 679: //----------------------------------------------------------------------- ! 680: void FDC_TypeI_Restore(void) ! 681: { ! 682: // Set emulation to seek to track zero ! 683: FDCEmulationCommand = FDCEMU_CMD_RESTORE; ! 684: FDCEmulationRunning = FDCEMU_RUN_RESTORE_SEEKTOTRACKZERO; ! 685: ! 686: FDC_SetDiscControllerStatus(); ! 687: } ! 688: ! 689: //----------------------------------------------------------------------- ! 690: void FDC_TypeI_Seek(void) ! 691: { ! 692: // Set emulation to seek to chosen track ! 693: FDCEmulationCommand = FDCEMU_CMD_SEEK; ! 694: FDCEmulationRunning = FDCEMU_RUN_SEEK_TOTRACK; ! 695: ! 696: FDC_SetDiscControllerStatus(); ! 697: } ! 698: ! 699: //----------------------------------------------------------------------- ! 700: void FDC_TypeI_Step(void) ! 701: { ! 702: // Set emulation to step(same direction as last seek executed, eg 'FDCStepDirection') ! 703: FDCEmulationCommand = FDCEMU_CMD_STEP; ! 704: FDCEmulationRunning = FDCEMU_RUN_STEP_ONCE; ! 705: ! 706: FDC_SetDiscControllerStatus(); ! 707: } ! 708: ! 709: //----------------------------------------------------------------------- ! 710: void FDC_TypeI_StepIn(void) ! 711: { ! 712: // Set emulation to step in(Set 'FDCStepDirection') ! 713: FDCEmulationCommand = FDCEMU_CMD_STEPIN; ! 714: FDCEmulationRunning = FDCEMU_RUN_STEPIN_ONCE; ! 715: FDCStepDirection = 1; // Increment track ! 716: ! 717: FDC_SetDiscControllerStatus(); ! 718: } ! 719: ! 720: //----------------------------------------------------------------------- ! 721: void FDC_TypeI_StepOut(void) ! 722: { ! 723: // Set emulation to step out(Set 'FDCStepDirection') ! 724: FDCEmulationCommand = FDCEMU_CMD_STEPOUT; ! 725: FDCEmulationRunning = FDCEMU_RUN_STEPOUT_ONCE; ! 726: FDCStepDirection = -1; // Decrement track ! 727: ! 728: FDC_SetDiscControllerStatus(); ! 729: } ! 730: ! 731: //----------------------------------------------------------------------- ! 732: /* ! 733: Type II Commands ! 734: ! 735: Read Sector, Read Multiple Sectors, Write Sector, Write Multiple Sectors ! 736: */ ! 737: ! 738: //----------------------------------------------------------------------- ! 739: void FDC_TypeII_ReadSector(void) ! 740: { ! 741: // Set emulation to read a single sector ! 742: FDCEmulationCommand = FDCEMU_CMD_READSECTORS; ! 743: FDCEmulationRunning = FDCEMU_RUN_READSECTORS_READDATA; ! 744: // Set reading parameters ! 745: FDC_SetReadWriteParameters(1); // Read in a single sector ! 746: ! 747: FDC_SetDiscControllerStatus(); ! 748: } ! 749: ! 750: //----------------------------------------------------------------------- ! 751: void FDC_TypeII_ReadMultipleSectors(void) ! 752: { ! 753: // Set emulation to read sectors ! 754: FDCEmulationCommand = FDCEMU_CMD_READMULTIPLESECTORS; ! 755: FDCEmulationRunning = FDCEMU_RUN_READSECTORS_READDATA; ! 756: // Set reading parameters ! 757: FDC_SetReadWriteParameters(FDCSectorCountRegister); // Read multiple sectors ! 758: ! 759: FDC_SetDiscControllerStatus(); ! 760: } ! 761: ! 762: //----------------------------------------------------------------------- ! 763: void FDC_TypeII_WriteSector(void) ! 764: { ! 765: // Set emulation to write a single sector ! 766: FDCEmulationCommand = FDCEMU_CMD_WRITESECTORS; ! 767: FDCEmulationRunning = FDCEMU_RUN_WRITESECTORS_WRITEDATA; ! 768: // Set writing parameters ! 769: FDC_SetReadWriteParameters(1); // Write out a single sector ! 770: ! 771: FDC_SetDiscControllerStatus(); ! 772: } ! 773: ! 774: //----------------------------------------------------------------------- ! 775: void FDC_TypeII_WriteMultipleSectors(void) ! 776: { ! 777: // Set emulation to write sectors ! 778: FDCEmulationCommand = FDCEMU_CMD_WRITEMULTIPLESECTORS; ! 779: FDCEmulationRunning = FDCEMU_RUN_WRITESECTORS_WRITEDATA; ! 780: // Set witing parameters ! 781: FDC_SetReadWriteParameters(FDCSectorCountRegister); // Write multiple sectors ! 782: ! 783: FDC_SetDiscControllerStatus(); ! 784: } ! 785: ! 786: //----------------------------------------------------------------------- ! 787: /* ! 788: Type III Commands ! 789: ! 790: Read Address, Read Track, Write Track ! 791: */ ! 792: ! 793: //----------------------------------------------------------------------- ! 794: void FDC_TypeIII_ReadAddress(void) ! 795: { ! 796: } ! 797: ! 798: //----------------------------------------------------------------------- ! 799: void FDC_TypeIII_ReadTrack(void) ! 800: { ! 801: // Set emulation to read a single track ! 802: FDCEmulationCommand = FDCEMU_CMD_READSECTORS; ! 803: FDCEmulationRunning = FDCEMU_RUN_READSECTORS_READDATA; ! 804: // Set reading parameters ! 805: FDC_SetReadWriteParameters(nReadWriteSectorsPerTrack); // Read whole track ! 806: ! 807: FDC_SetDiscControllerStatus(); ! 808: } ! 809: ! 810: //----------------------------------------------------------------------- ! 811: void FDC_TypeIII_WriteTrack(void) ! 812: { ! 813: // Set emulation to write a single track ! 814: FDCEmulationCommand = FDCEMU_CMD_WRITESECTORS; ! 815: FDCEmulationRunning = FDCEMU_RUN_WRITESECTORS_WRITEDATA; ! 816: // Set writing parameters ! 817: FDC_SetReadWriteParameters(nReadWriteSectorsPerTrack); // Write whole track ! 818: ! 819: FDC_SetDiscControllerStatus(); ! 820: } ! 821: ! 822: //----------------------------------------------------------------------- ! 823: /* ! 824: Type IV Commands ! 825: ! 826: Force Interrupt ! 827: */ ! 828: ! 829: //----------------------------------------------------------------------- ! 830: void FDC_TypeIV_ForceInterrupt(BOOL bCauseCPUInterrupt) ! 831: { ! 832: // Acknowledge interrupt, move along there's nothing more to see ! 833: if (bCauseCPUInterrupt) ! 834: FDC_AcknowledgeInterrupt(); ! 835: ! 836: // Reset FDC ! 837: FDCEmulationCommand = FDCEMU_CMD_NULL; ! 838: FDCEmulationRunning = FDCEMU_RUN_NULL; ! 839: } ! 840: ! 841: //----------------------------------------------------------------------- ! 842: /* ! 843: Execute Type I commands ! 844: */ ! 845: void FDC_ExecuteTypeICommands(void) ! 846: { ! 847: MFP_GPIP |= 0x20; ! 848: ! 849: // Check Type I Command ! 850: switch(FDCCommandRegister&0xf0) { ! 851: case 0x00: // Restore ! 852: FDC_TypeI_Restore(); ! 853: break; ! 854: case 0x10: // Seek ! 855: FDC_TypeI_Seek(); ! 856: break; ! 857: case 0x20: // Step ! 858: case 0x30: ! 859: FDC_TypeI_Step(); ! 860: break; ! 861: case 0x40: // Step-In ! 862: case 0x50: ! 863: FDC_TypeI_StepIn(); ! 864: break; ! 865: case 0x60: // Step-Out ! 866: case 0x70: ! 867: FDC_TypeI_StepOut(); ! 868: break; ! 869: } ! 870: ! 871: // Signal motor on as we need to execute command ! 872: FDC_TurnMotorOn(); ! 873: } ! 874: ! 875: //----------------------------------------------------------------------- ! 876: /* ! 877: Execute Type II commands ! 878: */ ! 879: void FDC_ExecuteTypeIICommands(void) ! 880: { ! 881: MFP_GPIP |= 0x20; ! 882: ! 883: // Check Type II Command ! 884: switch(FDCCommandRegister&0xf0) { ! 885: case 0x80: // Read Sector ! 886: FDC_TypeII_ReadSector(); ! 887: break; ! 888: case 0x90: // Read Sectors ! 889: FDC_TypeII_ReadMultipleSectors(); ! 890: break; ! 891: case 0xa0: // Write Sector ! 892: FDC_TypeII_WriteSector(); ! 893: break; ! 894: case 0xb0: // Write Sectors ! 895: FDC_TypeII_WriteMultipleSectors(); ! 896: break; ! 897: } ! 898: ! 899: // Signal motor on as we need to execute command ! 900: FDC_TurnMotorOn(); ! 901: } ! 902: ! 903: //----------------------------------------------------------------------- ! 904: /* ! 905: Execute Type III commands ! 906: */ ! 907: void FDC_ExecuteTypeIIICommands(void) ! 908: { ! 909: MFP_GPIP |= 0x20; ! 910: ! 911: // Check Type III Command ! 912: switch(FDCCommandRegister&0xf0) { ! 913: case 0xc0: // Read Address ! 914: FDC_TypeIII_ReadAddress(); ! 915: break; ! 916: case 0xe0: // Read Track ! 917: FDC_TypeIII_ReadTrack(); ! 918: break; ! 919: case 0xf0: // Write Track ! 920: FDC_TypeIII_WriteTrack(); ! 921: break; ! 922: } ! 923: ! 924: // Signal motor on as we need to execute command ! 925: FDC_TurnMotorOn(); ! 926: } ! 927: ! 928: //----------------------------------------------------------------------- ! 929: /* ! 930: Execute Type IV commands ! 931: */ ! 932: void FDC_ExecuteTypeIVCommands(void) ! 933: { ! 934: if (FDCCommandRegister!=0xD8) /* Is an 'immediate interrupt command'? don't reset interrupt */ ! 935: MFP_GPIP |= 0x20; ! 936: ! 937: // Check Type IV Command ! 938: if ((FDCCommandRegister&0x0c)==0) /* I3 and I2 are clear? If so we don't need a CPU interrupt */ ! 939: FDC_TypeIV_ForceInterrupt(FALSE); /* Force Interrupt - no interrupt */ ! 940: else ! 941: FDC_TypeIV_ForceInterrupt(TRUE); /* Force Interrupt */ ! 942: } ! 943: ! 944: //----------------------------------------------------------------------- ! 945: /* ! 946: Find FDC command type and execute ! 947: */ ! 948: void FDC_ExecuteCommand(void) ! 949: { ! 950: /* Check type of command and execute */ ! 951: if ((FDCCommandRegister&0x80)==0) /* Type I - Restore,Seek,Step,Step-In,Step-Out */ ! 952: FDC_ExecuteTypeICommands(); ! 953: else if ((FDCCommandRegister&0x40)==0) /* Type II - Read Sector, Write Sector */ ! 954: FDC_ExecuteTypeIICommands(); ! 955: else if ((FDCCommandRegister&0xf0)!=0xd0) /* Type III - Read Address, Read Track, Write Track */ ! 956: FDC_ExecuteTypeIIICommands(); ! 957: else // Type IV - Force Interrupt ! 958: FDC_ExecuteTypeIVCommands(); ! 959: } ! 960: ! 961: //----------------------------------------------------------------------- ! 962: /* ! 963: Write to SectorCount register (WR 0xff8604) ! 964: */ ! 965: void FDC_WriteSectorCountRegister(void) ! 966: { ! 967: FDCSectorCountRegister = DiscControllerWord_ff8604wr; ! 968: } ! 969: ! 970: //----------------------------------------------------------------------- ! 971: /* ! 972: Write to Command register (WR 0xff8604) ! 973: */ ! 974: void FDC_WriteCommandRegister(void) ! 975: { ! 976: FDCCommandRegister = DiscControllerWord_ff8604wr; ! 977: /* And execute */ ! 978: FDC_ExecuteCommand(); ! 979: } ! 980: ! 981: //----------------------------------------------------------------------- ! 982: /* ! 983: Write to Track register (WR 0xff8604) ! 984: */ ! 985: void FDC_WriteTrackRegister(void) ! 986: { ! 987: FDCTrackRegister = DiscControllerWord_ff8604wr; /* 0...79 */ ! 988: } ! 989: ! 990: //----------------------------------------------------------------------- ! 991: /* ! 992: Write to Track register (WR 0xff8604) ! 993: */ ! 994: void FDC_WriteSectorRegister(void) ! 995: { ! 996: FDCSectorRegister = DiscControllerWord_ff8604wr; /* 1,2,3..... */ ! 997: } ! 998: ! 999: //----------------------------------------------------------------------- ! 1000: /* ! 1001: Write to Data register (WR 0xff8604) ! 1002: */ ! 1003: void FDC_WriteDataRegister(void) ! 1004: { ! 1005: FDCDataRegister = DiscControllerWord_ff8604wr; ! 1006: } ! 1007: ! 1008: //----------------------------------------------------------------------- ! 1009: /* ! 1010: Store byte in FDC registers, when write to 0xff8604 ! 1011: */ ! 1012: void FDC_WriteDiscControllerByte(void) ! 1013: { ! 1014: // Are we trying to set the SectorCount? ! 1015: if (DMAModeControl_ff8606wr&0x10) /* Bit 4 */ ! 1016: FDC_WriteSectorCountRegister(); ! 1017: else { // Write to FDC registers ! 1018: switch(DMAModeControl_ff8606wr&0x6) { /* Bits 1,2 (A1,A0) */ ! 1019: case 0x0: /* 0 0 - Command register */ ! 1020: FDC_WriteCommandRegister(); ! 1021: break; ! 1022: case 0x2: /* 0 1 - Track register */ ! 1023: FDC_WriteTrackRegister(); ! 1024: break; ! 1025: case 0x4: /* 1 0 - Sector register */ ! 1026: FDC_WriteSectorRegister(); ! 1027: break; ! 1028: case 0x6: /* 1 1 - Data register */ ! 1029: FDC_WriteDataRegister(); ! 1030: break; ! 1031: } ! 1032: } ! 1033: } ! 1034: ! 1035: //----------------------------------------------------------------------- ! 1036: /* ! 1037: Read Status/FDC registers, when read from 0xff8604 ! 1038: Return 'DiscControllerByte' ! 1039: */ ! 1040: void FDC_ReadDiscControllerStatusByte(void) ! 1041: { ! 1042: switch(DMAModeControl_ff8606wr&0x6) { /* Bits 1,2 (A1,A0) */ ! 1043: case 0x0: /* 0 0 - Status register */ ! 1044: DiscControllerByte = DiscControllerStatus_ff8604rd; ! 1045: if (bMotorOn) ! 1046: DiscControllerByte |= 0x80; ! 1047: ! 1048: /* Reset FDC GPIP */ ! 1049: MFP_GPIP |= 0x20; ! 1050: break; ! 1051: case 0x2: /* 0 1 - Track register */ ! 1052: DiscControllerByte = FDCTrackRegister; ! 1053: break; ! 1054: case 0x4: /* 1 0 - Sector register */ ! 1055: DiscControllerByte = FDCSectorRegister; ! 1056: break; ! 1057: case 0x6: /* 1 1 - Data register */ ! 1058: DiscControllerByte = FDCDataRegister; ! 1059: break; ! 1060: } ! 1061: } ! 1062: ! 1063: //----------------------------------------------------------------------- ! 1064: /* ! 1065: Read DMA address from ST's RAM(always up-to-date) ! 1066: */ ! 1067: unsigned long FDC_ReadDMAAddress(void) ! 1068: { ! 1069: unsigned long Address; ! 1070: ! 1071: /* Build up 24-bit address from hardware registers */ ! 1072: Address = ((unsigned long)STMemory_ReadByte(0xff8609)<<16) | ((unsigned long)STMemory_ReadByte(0xff860b)<<8) | (unsigned long)STMemory_ReadByte(0xff860d); ! 1073: ! 1074: return(Address); ! 1075: } ! 1076: ! 1077: //----------------------------------------------------------------------- ! 1078: /* ! 1079: Write DMA address to ST's RAM(always keep up-to-date) ! 1080: */ ! 1081: void FDC_WriteDMAAddress(unsigned long Address) ! 1082: { ! 1083: /* Store as 24-bit address */ ! 1084: STMemory_WriteByte(0xff8609,Address>>16); ! 1085: STMemory_WriteByte(0xff860b,Address>>8); ! 1086: STMemory_WriteByte(0xff860d,Address); ! 1087: } ! 1088: ! 1089: //----------------------------------------------------------------------- ! 1090: /* ! 1091: Read sector from floppy drive into workspace ! 1092: We copy the bytes in chunks to simulate reading of the floppy using DMA ! 1093: */ ! 1094: BOOL FDC_ReadSectorFromFloppy(void) ! 1095: { ! 1096: // Copy in 1 sector to our workspace ! 1097: if (Floppy_ReadSectors(nReadWriteDev,(char *)DMASectorWorkSpace,nReadWriteSector,nReadWriteTrack,nReadWriteSide,1,NULL)) { ! 1098: // Update reading/writing parameters ! 1099: nReadWriteSector++; ! 1100: if (nReadWriteSector>nReadWriteSectorsPerTrack) { // Advance into next track? ! 1101: nReadWriteSector = 1; ! 1102: nReadWriteTrack++; ! 1103: } ! 1104: return(TRUE); ! 1105: } ! 1106: ! 1107: // Failed ! 1108: return(FALSE); ! 1109: } ! 1110: ! 1111: //----------------------------------------------------------------------- ! 1112: /* ! 1113: Write sector from workspace to floppy drive ! 1114: We copy the bytes in chunks to simulate writing of the floppy using DMA ! 1115: */ ! 1116: BOOL FDC_WriteSectorFromFloppy(void) ! 1117: { ! 1118: unsigned long Address; ! 1119: ! 1120: // Get DMA address ! 1121: Address = FDC_ReadDMAAddress(); ! 1122: ! 1123: // Write out 1 sector from our workspace ! 1124: if (Floppy_WriteSectors(nReadWriteDev,(char *)((unsigned long)STRam+Address),nReadWriteSector,nReadWriteTrack,nReadWriteSide,1,NULL)) { ! 1125: // Update reading/writing parameters ! 1126: nReadWriteSector++; ! 1127: if (nReadWriteSector>nReadWriteSectorsPerTrack) { // Advance to next track? ! 1128: nReadWriteSector = 1; ! 1129: nReadWriteTrack++; ! 1130: } ! 1131: return(TRUE); ! 1132: } ! 1133: ! 1134: // Failed ! 1135: return(FALSE); ! 1136: } ! 1137: ! 1138: ! 1139: //----------------------------------------------------------------------- ! 1140: /* ! 1141: Copy data from DMA workspace into ST RAM ! 1142: */ ! 1143: void FDC_DMADataFromFloppy(void) ! 1144: { ! 1145: // Copy data to DMA address ! 1146: memcpy( (char *)((unsigned long)STRam+FDC_ReadDMAAddress()), DMASectorWorkSpace, NUMBYTESPERSECTOR ); ! 1147: ! 1148: // Update DMA pointer ! 1149: FDC_WriteDMAAddress(FDC_ReadDMAAddress()+NUMBYTESPERSECTOR); ! 1150: } ! 1151: ! 1152: ! 1153: //----------------------------------------------------------------------- ! 1154: /* ! 1155: Write byte to 0xff8604 ! 1156: */ ! 1157: void FDC_WriteDiscController(unsigned short v) ! 1158: { ! 1159: DiscControllerWord_ff8604wr = v; ! 1160: FDC_WriteDiscControllerByte(); ! 1161: } ! 1162: ! 1163: ! 1164: //----------------------------------------------------------------------- ! 1165: /* ! 1166: Read word from 0xff8604 ! 1167: */ ! 1168: short FDC_ReadDiscControllerStatus(void) ! 1169: { ! 1170: FDC_ReadDiscControllerStatusByte(); /* Read Status/Track/Sector/Data according to 'DiscControllerWord_ff8604wr' */ ! 1171: return DiscControllerByte; ! 1172: } ! 1173: ! 1174: ! 1175: //----------------------------------------------------------------------- ! 1176: /* ! 1177: Write word to 0xff8606 (DMA Mode Control) ! 1178: ! 1179: Eg. ! 1180: $80 - Selects command/status register ! 1181: $82 - Selects track register ! 1182: $84 - Selects sector register ! 1183: $86 - Selects data regsiter ! 1184: NOTE - OR above values with $100 is transfer from memory to floppy ! 1185: Also if bit 4 is set, write to sector count register ! 1186: */ ! 1187: void FDC_WriteDMAModeControl(unsigned short v) ! 1188: { ! 1189: DMAModeControl_ff8606wr_prev = DMAModeControl_ff8606wr; /* Store previous to check for _read/_write toggle(DMA reset) */ ! 1190: DMAModeControl_ff8606wr = v; /* Store to DMA Mode control */ ! 1191: FDC_CheckForDMAStatusReset(); ! 1192: } ! 1193:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.