|
|
1.1 ! root 1: /* Previous - mo.c ! 2: ! 3: This file is distributed under the GNU Public License, version 2 or at ! 4: your option any later version. Read the file gpl.txt for details. ! 5: ! 6: Canon Magneto-optical Disk Drive Emulation. ! 7: ! 8: Based on MESS source code. ! 9: ! 10: NeXT Optical Storage Processor uses Reed-Solomon algorithm for error correction. ! 11: It has 2 128 byte internal buffers and uses double-buffering to perform error correction. ! 12: ! 13: Dummy to pass POT. ! 14: ! 15: */ ! 16: ! 17: #include "ioMem.h" ! 18: #include "ioMemTables.h" ! 19: #include "m68000.h" ! 20: #include "configuration.h" ! 21: #include "mo.h" ! 22: #include "sysReg.h" ! 23: #include "dma.h" ! 24: ! 25: #define LOG_MO_LEVEL LOG_WARN ! 26: #define IO_SEG_MASK 0x1FFFF ! 27: ! 28: ! 29: struct { ! 30: Uint16 track_num; ! 31: Uint8 sector_incrnum; ! 32: Uint8 sector_count; ! 33: Uint8 intstatus; ! 34: Uint8 intmask; ! 35: Uint8 ctrlr_csr2; ! 36: Uint8 ctrlr_csr1; ! 37: Uint16 command; ! 38: } mo_drive; ! 39: ! 40: Uint8 ECC_buffer[1600]; ! 41: Uint32 length; ! 42: Uint8 sector_position; ! 43: ! 44: /* MO Drive Registers */ ! 45: #define MO_INTSTATUS 4 ! 46: #define MO_INTMASK 5 ! 47: #define MO_CTRLR_CSR2 6 ! 48: #define MO_CTRLR_CSR1 7 ! 49: #define MO_COMMAND_HI 8 ! 50: #define MO_COMMAND_LO 9 ! 51: #define MO_INIT 12 ! 52: #define MO_FORMAT 13 ! 53: #define MO_MARK 14 ! 54: ! 55: /* MO Drive Register Constants */ ! 56: #define INTSTAT_CLR 0xFC ! 57: #define INTSTAT_RESET 0x01 ! 58: // controller csr 2 ! 59: #define ECC_MODE 0x20 ! 60: // controller csr 1 ! 61: #define ECC_READ 0x80 ! 62: #define ECC_WRITE 0x40 ! 63: ! 64: // drive commands ! 65: #define OD_SEEK 0x0000 ! 66: #define OD_HOS 0xA000 ! 67: #define OD_RECALIB 0x1000 ! 68: #define OD_RDS 0x2000 ! 69: #define OD_RCA 0x2200 ! 70: ! 71: #define OD_RID 0x5000 ! 72: ! 73: void check_ecc(void); ! 74: void compute_ecc(void); ! 75: ! 76: ! 77: void MOdrive_Read(void) { ! 78: Uint8 val; ! 79: Uint8 reg = IoAccessCurrentAddress&0x1F; ! 80: ! 81: switch (reg) { ! 82: case MO_INTSTATUS: ! 83: val = mo_drive.intstatus; ! 84: mo_drive.intstatus |= 0x01; ! 85: break; ! 86: ! 87: case MO_INTMASK: ! 88: val = mo_drive.intmask; ! 89: break; ! 90: ! 91: case MO_CTRLR_CSR2: ! 92: val = mo_drive.ctrlr_csr2; ! 93: break; ! 94: ! 95: case MO_CTRLR_CSR1: ! 96: val = mo_drive.ctrlr_csr1; ! 97: break; ! 98: ! 99: case MO_COMMAND_HI: ! 100: val = 0x00; ! 101: break; ! 102: ! 103: case MO_COMMAND_LO: ! 104: val = 0x00; ! 105: break; ! 106: ! 107: case 10: ! 108: val = 0x00; ! 109: break; ! 110: ! 111: case 11: ! 112: val = 0x24; ! 113: break; ! 114: ! 115: case 16: ! 116: val = 0x00; ! 117: break; ! 118: ! 119: default: ! 120: break; ! 121: } ! 122: ! 123: IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = val; ! 124: Log_Printf(LOG_MO_LEVEL, "[MO Drive] read reg %d val %02x PC=%x %s at %d",reg,val,m68k_getpc(),__FILE__,__LINE__); ! 125: } ! 126: ! 127: ! 128: void MOdrive_Write(void) { ! 129: Uint8 val = IoMem[IoAccessCurrentAddress & IO_SEG_MASK]; ! 130: Uint8 reg = IoAccessCurrentAddress&0x1F; ! 131: ! 132: Log_Printf(LOG_MO_LEVEL, "[MO Drive] write reg %d val %02x PC=%x %s at %d",reg,val,m68k_getpc(),__FILE__,__LINE__); ! 133: ! 134: switch (reg) { ! 135: case MO_INTSTATUS: // reg 4 ! 136: switch (val) { ! 137: case INTSTAT_CLR: ! 138: mo_drive.intstatus &= 0x02; ! 139: mo_drive.intstatus |= 0x01; ! 140: break; ! 141: ! 142: case INTSTAT_RESET: ! 143: mo_drive.intstatus |= 0x01; ! 144: //MOdrive_Reset(); ! 145: ! 146: default: ! 147: break; ! 148: ! 149: //mo_drive.intstatus = (mo_drive.intstatus & (~val & 0xfc)) | (val & 3); ! 150: } ! 151: break; ! 152: ! 153: case MO_INTMASK: // reg 5 ! 154: mo_drive.intmask = val; ! 155: break; ! 156: ! 157: case MO_CTRLR_CSR2: // reg 6 ! 158: mo_drive.ctrlr_csr2 = val; ! 159: break; ! 160: ! 161: case MO_CTRLR_CSR1: // reg 7 ! 162: mo_drive.ctrlr_csr1 = val; ! 163: switch (mo_drive.ctrlr_csr1) { ! 164: case ECC_WRITE: ! 165: dma_memory_read(ECC_buffer, &length, CHANNEL_DISK); ! 166: mo_drive.intstatus |= 0xFF; ! 167: if (mo_drive.ctrlr_csr2&ECC_MODE) ! 168: check_ecc(); ! 169: else ! 170: compute_ecc(); ! 171: break; ! 172: ! 173: case ECC_READ: ! 174: dma_memory_write(ECC_buffer, length, CHANNEL_DISK); ! 175: mo_drive.intstatus |= 0xFF; ! 176: break; ! 177: ! 178: case 0x20: // RD_STAT ! 179: mo_drive.intstatus |= 0x01; // set cmd complete ! 180: break; ! 181: ! 182: default: ! 183: break; ! 184: } ! 185: break; ! 186: case MO_COMMAND_HI: ! 187: mo_drive.command = (val << 8)&0xFF00; ! 188: break; ! 189: case MO_COMMAND_LO: ! 190: mo_drive.command |= val&0xFF; ! 191: MOdrive_Execute_Command(mo_drive.command); ! 192: // mo_drive.intstatus &= ~0x01; // release cmd complete ! 193: // set_interrupt(INT_DISK, SET_INT); ! 194: break; ! 195: ! 196: case MO_INIT: // reg 12 ! 197: if (val&0x80) { // sector > enable ! 198: printf("MO Init: sector > enable\n"); ! 199: } ! 200: if (val&0x40) { // ECC starve disable ! 201: printf("MO Init: ECC starve disable\n"); ! 202: } ! 203: if (val&0x20) { // ID cmp on track, not sector ! 204: printf("MO Init: ID cmp on track not sector\n"); ! 205: } ! 206: if (val&0x10) { // 25 MHz ECC clk for 3600 RPM ! 207: printf("MO Init: 25 MHz ECC clk for 3600 RPM\n"); ! 208: } ! 209: if (val&0x08) { // DMA starve enable ! 210: printf("MO Init: DMA starve enable\n"); ! 211: } ! 212: if (val&0x04) { // diag: generate bad parity ! 213: printf("MO Init: diag: generate bad parity\n"); ! 214: } ! 215: if (val&0x03) { ! 216: printf("MO Init: %i IDs must match\n", val&0x03); ! 217: } ! 218: break; ! 219: ! 220: case MO_FORMAT: // reg 13 ! 221: break; ! 222: ! 223: case MO_MARK: // reg 14 ! 224: break; ! 225: ! 226: case 16: ! 227: case 17: ! 228: case 18: ! 229: case 19: ! 230: case 20: ! 231: case 21: ! 232: case 22: ! 233: break; // flag strategy ! 234: ! 235: default: ! 236: break; ! 237: } ! 238: } ! 239: ! 240: ! 241: void MOdrive_Execute_Command(Uint16 command) { ! 242: mo_drive.intstatus &= ~0x01; // release cmd complete ! 243: switch (command) { ! 244: case OD_SEEK: ! 245: // set_interrupt(INT_DISK, SET_INT); ! 246: break; ! 247: case OD_RDS: ! 248: break; ! 249: ! 250: case OD_RID: ! 251: break; ! 252: ! 253: default: ! 254: break; ! 255: } ! 256: } ! 257: ! 258: ! 259: void check_ecc(void) { ! 260: int i; ! 261: for(i=0; i<0x400; i++) ! 262: ECC_buffer[i] = i; ! 263: } ! 264: ! 265: void compute_ecc(void) { ! 266: memset(ECC_buffer+0x400, 0, 0x110); ! 267: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.