|
|
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.