1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * SCSI and SASI emulation (not uaescsi.device)
5 *
6 * Copyright 2007-2015 Toni Wilen
7 *
8 */
9
10 #include "sysconfig.h"
11 #include "sysdeps.h"
12
13 #include "options.h"
14 #include "filesys.h"
15 #include "blkdev.h"
16 #include "zfile.h"
17 #include "debug.h"
18 #include "memory.h"
19 #include "scsi.h"
20 #include "autoconf.h"
21 #include "rommgr.h"
22 #include "newcpu.h"
23 #include "custom.h"
24 #include "gayle.h"
25 #include "cia.h"
26 #include "x86.h"
27
28 #define SCSI_EMU_DEBUG 0
29 #define RAW_SCSI_DEBUG 1
30 #define NCR5380_DEBUG 0
31 #define NCR5380_DEBUG_IRQ 0
32
33 #define NCR5380_SUPRA 1
34 #define NONCR_GOLEM 2
35 #define NCR5380_STARDRIVE 3
36 #define NONCR_KOMMOS 4
37 #define NONCR_VECTOR 5
38 #define NONCR_APOLLO 6
39 #define NCR5380_PROTAR 7
40 #define NCR5380_ADD500 8
41 #define NCR5380_KRONOS 9
42 #define NCR5380_ADSCSI 10
43 #define NCR5380_ROCHARD 11
44 #define NCR5380_CLTD 12
45 #define NCR5380_PTNEXUS 13
46 #define NCR5380_DATAFLYER 14
47 #define NONCR_TECMAR 15
48 #define NCR5380_XEBEC 16
49 #define NONCR_MICROFORGE 17
50 #define NONCR_PARADOX 18
51 #define OMTI_HDA506 19
52 #define OMTI_ALF1 20
53 #define OMTI_PROMIGOS 21
54 #define OMTI_SYSTEM2000 22
55 #define OMTI_ADAPTER 23
56 #define OMTI_X86 24
57 #define NCR5380_PHOENIXBOARD 25
58 #define NCR_LAST 26
59
60 extern int log_scsiemu;
61
62 static const int outcmd[] = { 0x04, 0x0a, 0x0c, 0x2a, 0xaa, 0x15, 0x55, 0x0f, -1 };
63 static const int incmd[] = { 0x01, 0x03, 0x08, 0x12, 0x1a, 0x5a, 0x25, 0x28, 0x34, 0x37, 0x42, 0x43, 0xa8, 0x51, 0x52, 0xb9, 0xbd, 0xbe, -1 };
64 static const int nonecmd[] = { 0x00, 0x05, 0x09, 0x0b, 0x11, 0x16, 0x17, 0x19, 0x1b, 0x1e, 0x2b, 0x35, 0xe0, 0xe3, 0xe4, -1 };
65 static const int scsicmdsizes[] = { 6, 10, 10, 12, 16, 12, 10, 6 };
66
scsi_illegal_command(struct scsi_data * sd)67 static void scsi_illegal_command(struct scsi_data *sd)
68 {
69 uae_u8 *s = sd->sense;
70
71 memset (s, 0, sizeof (sd->sense));
72 sd->status = SCSI_STATUS_CHECK_CONDITION;
73 s[0] = 0x70;
74 s[2] = 5; /* ILLEGAL REQUEST */
75 s[12] = 0x24; /* ILLEGAL FIELD IN CDB */
76 sd->sense_len = 0x12;
77 }
78
scsi_grow_buffer(struct scsi_data * sd,int newsize)79 static void scsi_grow_buffer(struct scsi_data *sd, int newsize)
80 {
81 if (sd->buffer_size >= newsize)
82 return;
83 uae_u8 *oldbuf = sd->buffer;
84 int oldsize = sd->buffer_size;
85 sd->buffer_size = newsize + SCSI_DEFAULT_DATA_BUFFER_SIZE;
86 write_log(_T("SCSI buffer %d -> %d\n"), oldsize, sd->buffer_size);
87 sd->buffer = xmalloc(uae_u8, sd->buffer_size);
88 memcpy(sd->buffer, oldbuf, oldsize);
89 xfree(oldbuf);
90 }
91
scsi_data_dir(struct scsi_data * sd)92 static int scsi_data_dir(struct scsi_data *sd)
93 {
94 int i;
95 uae_u8 cmd;
96
97 cmd = sd->cmd[0];
98 for (i = 0; outcmd[i] >= 0; i++) {
99 if (cmd == outcmd[i]) {
100 return 1;
101 }
102 }
103 for (i = 0; incmd[i] >= 0; i++) {
104 if (cmd == incmd[i]) {
105 return -1;
106 }
107 }
108 for (i = 0; nonecmd[i] >= 0; i++) {
109 if (cmd == nonecmd[i]) {
110 return 0;
111 }
112 }
113 write_log (_T("SCSI command %02X, no direction specified!\n"), sd->cmd[0]);
114 return 0;
115 }
116
scsi_emulate_analyze(struct scsi_data * sd)117 bool scsi_emulate_analyze (struct scsi_data *sd)
118 {
119 int cmd_len, data_len, data_len2, tmp_len;
120
121 data_len = sd->data_len;
122 data_len2 = 0;
123 cmd_len = scsicmdsizes[sd->cmd[0] >> 5];
124 if (sd->hfd && sd->hfd->ansi_version < 2 && cmd_len > 10)
125 goto nocmd;
126 sd->cmd_len = cmd_len;
127 switch (sd->cmd[0])
128 {
129 case 0x04: // FORMAT UNIT
130 if (sd->device_type == UAEDEV_CD)
131 goto nocmd;
132 // FmtData set?
133 if (sd->cmd[1] & 0x10) {
134 int cl = (sd->cmd[1] & 8) != 0;
135 int dlf = sd->cmd[1] & 7;
136 data_len2 = 4;
137 } else {
138 sd->direction = 0;
139 sd->data_len = 0;
140 return true;
141 }
142 break;
143 case 0x0c: // INITIALIZE DRIVE CHARACTERICS (SASI)
144 if (sd->hfd && sd->hfd->hfd.ci.unit_feature_level < HD_LEVEL_SASI)
145 goto nocmd;
146 data_len = 8;
147 break;
148 case 0x08: // READ(6)
149 data_len2 = sd->cmd[4] * sd->blocksize;
150 scsi_grow_buffer(sd, data_len2);
151 break;
152 case 0x28: // READ(10)
153 data_len2 = ((sd->cmd[7] << 8) | (sd->cmd[8] << 0)) * (uae_s64)sd->blocksize;
154 scsi_grow_buffer(sd, data_len2);
155 break;
156 case 0xa8: // READ(12)
157 data_len2 = ((sd->cmd[6] << 24) | (sd->cmd[7] << 16) | (sd->cmd[8] << 8) | (sd->cmd[9] << 0)) * (uae_s64)sd->blocksize;
158 scsi_grow_buffer(sd, data_len2);
159 break;
160 case 0x0f: // WRITE SECTOR BUFFER
161 data_len = sd->blocksize;
162 scsi_grow_buffer(sd, data_len);
163 break;
164 case 0x0a: // WRITE(6)
165 if (sd->device_type == UAEDEV_CD)
166 goto nocmd;
167 data_len = sd->cmd[4] * sd->blocksize;
168 scsi_grow_buffer(sd, data_len);
169 break;
170 case 0x2a: // WRITE(10)
171 if (sd->device_type == UAEDEV_CD)
172 goto nocmd;
173 data_len = ((sd->cmd[7] << 8) | (sd->cmd[8] << 0)) * (uae_s64)sd->blocksize;
174 scsi_grow_buffer(sd, data_len);
175 break;
176 case 0xaa: // WRITE(12)
177 if (sd->device_type == UAEDEV_CD)
178 goto nocmd;
179 data_len = ((sd->cmd[6] << 24) | (sd->cmd[7] << 16) | (sd->cmd[8] << 8) | (sd->cmd[9] << 0)) * (uae_s64)sd->blocksize;
180 scsi_grow_buffer(sd, data_len);
181 break;
182 case 0xbe: // READ CD
183 case 0xb9: // READ CD MSF
184 if (sd->device_type != UAEDEV_CD)
185 goto nocmd;
186 tmp_len = (sd->cmd[6] << 16) | (sd->cmd[7] << 8) | sd->cmd[8];
187 // max block transfer size, it is usually smaller.
188 tmp_len *= 2352 + 96;
189 scsi_grow_buffer(sd, tmp_len);
190 break;
191 case 0x2f: // VERIFY
192 if (sd->cmd[1] & 2) {
193 sd->data_len = ((sd->cmd[7] << 8) | (sd->cmd[8] << 0)) * (uae_s64)sd->blocksize;
194 scsi_grow_buffer(sd, sd->data_len);
195 sd->direction = 1;
196 } else {
197 sd->data_len = 0;
198 sd->direction = 0;
199 }
200 return true;
201 case 0x15: // MODE SELECT
202 case 0x55:
203 if (sd->device_type != UAEDEV_CD && sd->device_type != UAEDEV_TAPE)
204 goto nocmd;
205 break;
206 }
207 if (data_len < 0) {
208 if (cmd_len == 6)
209 sd->data_len = sd->cmd[4];
210 else
211 sd->data_len = (sd->cmd[7] << 8) | sd->cmd[8];
212 } else {
213 sd->data_len = data_len;
214 }
215 sd->direction = scsi_data_dir (sd);
216 return true;
217 nocmd:
218 sd->status = SCSI_STATUS_CHECK_CONDITION;
219 sd->direction = 0;
220 scsi_illegal_command(sd);
221 return false;
222 }
223
scsi_illegal_lun(struct scsi_data * sd)224 void scsi_illegal_lun(struct scsi_data *sd)
225 {
226 uae_u8 *s = sd->sense;
227
228 memset (s, 0, sizeof (sd->sense));
229 sd->status = SCSI_STATUS_CHECK_CONDITION;
230 s[0] = 0x70;
231 s[2] = SCSI_SK_ILLEGAL_REQ;
232 s[12] = SCSI_INVALID_LUN;
233 sd->sense_len = 0x12;
234 }
235
scsi_clear_sense(struct scsi_data * sd)236 void scsi_clear_sense(struct scsi_data *sd)
237 {
238 memset (sd->sense, 0, sizeof (sd->sense));
239 memset (sd->reply, 0, sizeof (sd->reply));
240 sd->sense[0] = 0x70;
241 }
showsense(struct scsi_data * sd)242 static void showsense(struct scsi_data *sd)
243 {
244 if (log_scsiemu) {
245 for (int i = 0; i < sd->sense_len; i++) {
246 if (i > 0)
247 write_log (_T("."));
248 write_log (_T("%02X"), sd->buffer[i]);
249 }
250 write_log (_T("\n"));
251 }
252 }
copysense(struct scsi_data * sd)253 static void copysense(struct scsi_data *sd)
254 {
255 int len = sd->cmd[4];
256 if (log_scsiemu)
257 write_log (_T("REQUEST SENSE length %d (%d)\n"), len, sd->sense_len);
258 if (len == 0)
259 len = 4;
260 memset(sd->buffer, 0, len);
261 memcpy(sd->buffer, sd->sense, sd->sense_len > len ? len : sd->sense_len);
262 if (len > 7 && sd->sense_len > 7)
263 sd->buffer[7] = sd->sense_len - 8;
264 if (sd->sense_len == 0)
265 sd->buffer[0] = 0x70;
266 showsense (sd);
267 sd->data_len = len;
268 scsi_clear_sense(sd);
269 }
copyreply(struct scsi_data * sd)270 static void copyreply(struct scsi_data *sd)
271 {
272 if (sd->status == 0 && sd->reply_len > 0) {
273 memset(sd->buffer, 0, 256);
274 memcpy(sd->buffer, sd->reply, sd->reply_len);
275 sd->data_len = sd->reply_len;
276 }
277 }
278
scsi_set_unit_attention(struct scsi_data * sd,uae_u8 v1,uae_u8 v2)279 static void scsi_set_unit_attention(struct scsi_data *sd, uae_u8 v1, uae_u8 v2)
280 {
281 sd->unit_attention = (v1 << 8) | v2;
282 }
283
scsi_emulate_reset_device(struct scsi_data * sd)284 static void scsi_emulate_reset_device(struct scsi_data *sd)
285 {
286 if (!sd)
287 return;
288 if (sd->device_type == UAEDEV_HDF && sd->nativescsiunit < 0) {
289 scsi_clear_sense(sd);
290 // SCSI bus reset occurred
291 scsi_set_unit_attention(sd, 0x29, 0x02);
292 }
293 }
294
handle_ca(struct scsi_data * sd)295 static bool handle_ca(struct scsi_data *sd)
296 {
297 bool cc = sd->sense_len > 2 && sd->sense[2] >= 2;
298 bool ua = sd->unit_attention != 0;
299 uae_u8 cmd = sd->cmd[0];
300
301 // INQUIRY
302 if (cmd == 0x12) {
303 if (ua && cc && sd->sense[2] == 6) {
304 // INQUIRY clears UA only if previous
305 // command was aborted due to UA
306 sd->unit_attention = 0;
307 }
308 memset(sd->reply, 0, sizeof(sd->reply));
309 return true;
310 }
311
312 // REQUEST SENSE
313 if (cmd == 0x03) {
314 if (ua) {
315 uae_u8 *s = sd->sense;
316 scsi_clear_sense(sd);
317 s[0] = 0x70;
318 s[2] = 6; /* UNIT ATTENTION */
319 s[12] = (sd->unit_attention >> 8) & 0xff;
320 s[13] = (sd->unit_attention >> 0) & 0xff;
321 sd->sense_len = 0x12;
322 }
323 sd->unit_attention = 0;
324 return true;
325 }
326
327 scsi_clear_sense(sd);
328
329 if (ua) {
330 uae_u8 *s = sd->sense;
331 s[0] = 0x70;
332 s[2] = 6; /* UNIT ATTENTION */
333 s[12] = (sd->unit_attention >> 8) & 0xff;
334 s[13] = (sd->unit_attention >> 0) & 0xff;
335 sd->sense_len = 0x12;
336 sd->unit_attention = 0;
337 sd->status = 2;
338 return false;
339 }
340
341 return true;
342 }
343
scsi_emulate_cmd(struct scsi_data * sd)344 void scsi_emulate_cmd(struct scsi_data *sd)
345 {
346 sd->status = 0;
347 if ((sd->message[0] & 0xc0) == 0x80 && (sd->message[0] & 0x1f)) {
348 uae_u8 lun = sd->message[0] & 0x1f;
349 if (lun > 7)
350 lun = 7;
351 sd->cmd[1] &= ~(7 << 5);
352 sd->cmd[1] |= lun << 5;
353 }
354 #if SCSI_EMU_DEBUG
355 write_log (_T("CMD=%02x.%02x.%02x.%02x.%02x.%02x (%d,%d)\n"),
356 sd->cmd[0], sd->cmd[1], sd->cmd[2], sd->cmd[3], sd->cmd[4], sd->cmd[5], sd->device_type, sd->nativescsiunit);
357 #endif
358 if (sd->device_type == UAEDEV_CD && sd->cd_emu_unit >= 0) {
359 uae_u32 ua = 0;
360 ua = scsi_cd_emulate(sd->cd_emu_unit, NULL, 0, 0, 0, 0, 0, 0, 0, sd->atapi);
361 if (ua)
362 sd->unit_attention = ua;
363 if (handle_ca(sd)) {
364 if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */
365 scsi_cd_emulate(sd->cd_emu_unit, sd->cmd, 0, 0, 0, 0, 0, 0, 0, sd->atapi); /* ack request sense */
366 copysense(sd);
367 } else {
368 sd->status = scsi_cd_emulate(sd->cd_emu_unit, sd->cmd, sd->cmd_len, sd->buffer, &sd->data_len, sd->reply, &sd->reply_len, sd->sense, &sd->sense_len, sd->atapi);
369 copyreply(sd);
370 }
371 }
372 } else if (sd->device_type == UAEDEV_HDF && sd->nativescsiunit < 0) {
373 uae_u32 ua = 0;
374 ua = scsi_hd_emulate(&sd->hfd->hfd, sd->hfd, NULL, 0, 0, 0, 0, 0, 0, 0);
375 if (ua)
376 sd->unit_attention = ua;
377 if (handle_ca(sd)) {
378 if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */
379 scsi_hd_emulate(&sd->hfd->hfd, sd->hfd, sd->cmd, 0, 0, 0, 0, 0, sd->sense, &sd->sense_len);
380 copysense(sd);
381 } else {
382 sd->status = scsi_hd_emulate(&sd->hfd->hfd, sd->hfd,
383 sd->cmd, sd->cmd_len, sd->buffer, &sd->data_len, sd->reply, &sd->reply_len, sd->sense, &sd->sense_len);
384 copyreply(sd);
385 }
386 }
387 } else if (sd->device_type == UAEDEV_TAPE && sd->nativescsiunit < 0) {
388 uae_u32 ua = 0;
389 ua = scsi_tape_emulate(sd->tape, NULL, 0, 0, 0, 0, 0, 0, 0);
390 if (ua)
391 sd->unit_attention = ua;
392 if (handle_ca(sd)) {
393 if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */
394 scsi_tape_emulate(sd->tape, sd->cmd, 0, 0, 0, sd->reply, &sd->reply_len, sd->sense, &sd->sense_len); /* get request sense extra bits */
395 copysense(sd);
396 } else {
397 sd->status = scsi_tape_emulate(sd->tape,
398 sd->cmd, sd->cmd_len, sd->buffer, &sd->data_len, sd->reply, &sd->reply_len, sd->sense, &sd->sense_len);
399 copyreply(sd);
400 }
401 }
402 } else if (sd->nativescsiunit >= 0) {
403 struct amigascsi as;
404
405 memset(sd->sense, 0, 256);
406 memset(&as, 0, sizeof as);
407 memcpy (&as.cmd, sd->cmd, sd->cmd_len);
408 as.flags = 2 | 1;
409 if (sd->direction > 0)
410 as.flags &= ~1;
411 as.sense_len = 32;
412 as.cmd_len = sd->cmd_len;
413 as.data = sd->buffer;
414 as.len = sd->direction < 0 ? DEVICE_SCSI_BUFSIZE : sd->data_len;
415 sys_command_scsi_direct_native(sd->nativescsiunit, -1, &as);
416 sd->status = as.status;
417 sd->data_len = as.len;
418 if (sd->status) {
419 sd->direction = 0;
420 sd->data_len = 0;
421 memcpy(sd->sense, as.sensedata, as.sense_len);
422 }
423 }
424 sd->offset = 0;
425 }
426
allocscsibuf(struct scsi_data * sd)427 static void allocscsibuf(struct scsi_data *sd)
428 {
429 sd->buffer_size = SCSI_DEFAULT_DATA_BUFFER_SIZE;
430 sd->buffer = xcalloc(uae_u8, sd->buffer_size);
431 }
432
scsi_alloc_hd(int id,struct hd_hardfiledata * hfd)433 struct scsi_data *scsi_alloc_hd(int id, struct hd_hardfiledata *hfd)
434 {
435 struct scsi_data *sd = xcalloc (struct scsi_data, 1);
436 sd->hfd = hfd;
437 sd->id = id;
438 sd->nativescsiunit = -1;
439 sd->cd_emu_unit = -1;
440 sd->blocksize = hfd->hfd.ci.blocksize;
441 sd->device_type = UAEDEV_HDF;
442 allocscsibuf(sd);
443 return sd;
444 }
445
scsi_alloc_cd(int id,int unitnum,bool atapi)446 struct scsi_data *scsi_alloc_cd(int id, int unitnum, bool atapi)
447 {
448 struct scsi_data *sd;
449 if (!sys_command_open (unitnum)) {
450 write_log (_T("SCSI: CD EMU scsi unit %d failed to open\n"), unitnum);
451 return NULL;
452 }
453 sd = xcalloc (struct scsi_data, 1);
454 sd->id = id;
455 sd->cd_emu_unit = unitnum;
456 sd->nativescsiunit = -1;
457 sd->atapi = atapi;
458 sd->blocksize = 2048;
459 sd->device_type = UAEDEV_CD;
460 allocscsibuf(sd);
461 return sd;
462 }
463
scsi_alloc_tape(int id,const TCHAR * tape_directory,bool readonly)464 struct scsi_data *scsi_alloc_tape(int id, const TCHAR *tape_directory, bool readonly)
465 {
466 struct scsi_data_tape *tape;
467 tape = tape_alloc (id, tape_directory, readonly);
468 if (!tape)
469 return NULL;
470 struct scsi_data *sd = xcalloc (struct scsi_data, 1);
471 sd->id = id;
472 sd->nativescsiunit = -1;
473 sd->cd_emu_unit = -1;
474 sd->blocksize = tape->blocksize;
475 sd->tape = tape;
476 sd->device_type = UAEDEV_TAPE;
477 allocscsibuf(sd);
478 return sd;
479 }
480
scsi_alloc_native(int id,int nativeunit)481 struct scsi_data *scsi_alloc_native(int id, int nativeunit)
482 {
483 struct scsi_data *sd;
484 if (!sys_command_open (nativeunit)) {
485 write_log (_T("SCSI: native scsi unit %d failed to open\n"), nativeunit);
486 return NULL;
487 }
488 sd = xcalloc (struct scsi_data, 1);
489 sd->id = id;
490 sd->nativescsiunit = nativeunit;
491 sd->cd_emu_unit = -1;
492 sd->blocksize = 2048;
493 sd->device_type = 0;
494 allocscsibuf(sd);
495 return sd;
496 }
497
scsi_reset(void)498 void scsi_reset(void)
499 {
500 //device_func_init (DEVICE_TYPE_SCSI);
501 }
502
scsi_free(struct scsi_data * sd)503 void scsi_free(struct scsi_data *sd)
504 {
505 if (!sd)
506 return;
507 if (sd->nativescsiunit >= 0) {
508 sys_command_close (sd->nativescsiunit);
509 sd->nativescsiunit = -1;
510 }
511 if (sd->cd_emu_unit >= 0) {
512 sys_command_close (sd->cd_emu_unit);
513 sd->cd_emu_unit = -1;
514 }
515 tape_free (sd->tape);
516 xfree(sd->buffer);
517 xfree(sd);
518 }
519
scsi_start_transfer(struct scsi_data * sd)520 void scsi_start_transfer(struct scsi_data *sd)
521 {
522 sd->offset = 0;
523 }
524
scsi_send_data(struct scsi_data * sd,uae_u8 b)525 int scsi_send_data(struct scsi_data *sd, uae_u8 b)
526 {
527 if (sd->direction == 1) {
528 if (sd->offset >= sd->buffer_size) {
529 write_log (_T("SCSI data buffer overflow!\n"));
530 return 0;
531 }
532 sd->buffer[sd->offset++] = b;
533 } else if (sd->direction == 2) {
534 if (sd->offset >= 16) {
535 write_log (_T("SCSI command buffer overflow!\n"));
536 return 0;
537 }
538 sd->cmd[sd->offset++] = b;
539 if (sd->offset == sd->cmd_len)
540 return 1;
541 } else {
542 write_log (_T("scsi_send_data() without direction! (%02X)\n"), sd->cmd[0]);
543 return 0;
544 }
545 if (sd->offset == sd->data_len)
546 return 1;
547 return 0;
548 }
549
scsi_receive_data(struct scsi_data * sd,uae_u8 * b,bool next)550 int scsi_receive_data(struct scsi_data *sd, uae_u8 *b, bool next)
551 {
552 if (!sd->data_len)
553 return -1;
554 *b = sd->buffer[sd->offset];
555 if (next) {
556 sd->offset++;
557 if (sd->offset == sd->data_len)
558 return 1; // requested length got
559 }
560 return 0;
561 }
562
free_scsi(struct scsi_data * sd)563 void free_scsi (struct scsi_data *sd)
564 {
565 if (!sd)
566 return;
567 hdf_hd_close (sd->hfd);
568 scsi_free (sd);
569 }
570
add_scsi_hd(struct scsi_data ** sd,int ch,struct hd_hardfiledata * hfd,struct uaedev_config_info * ci)571 int add_scsi_hd (struct scsi_data **sd, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci)
572 {
573 free_scsi (*sd);
574 *sd = NULL;
575 if (!hfd) {
576 hfd = xcalloc (struct hd_hardfiledata, 1);
577 memcpy (&hfd->hfd.ci, ci, sizeof (struct uaedev_config_info));
578 }
579 if (!hdf_hd_open (hfd))
580 return 0;
581 hfd->ansi_version = ci->unit_feature_level + 1;
582 *sd = scsi_alloc_hd (ch, hfd);
583 return *sd ? 1 : 0;
584 }
585
add_scsi_cd(struct scsi_data ** sd,int ch,int unitnum)586 int add_scsi_cd (struct scsi_data **sd, int ch, int unitnum)
587 {
588 device_func_init (0);
589 free_scsi (*sd);
590 *sd = scsi_alloc_cd (ch, unitnum, false);
591 return *sd ? 1 : 0;
592 }
593
add_scsi_tape(struct scsi_data ** sd,int ch,const TCHAR * tape_directory,bool readonly)594 int add_scsi_tape (struct scsi_data **sd, int ch, const TCHAR *tape_directory, bool readonly)
595 {
596 free_scsi (*sd);
597 *sd = scsi_alloc_tape (ch, tape_directory, readonly);
598 return *sd ? 1 : 0;
599 }
600
add_scsi_device(struct scsi_data ** sd,int ch,struct uaedev_config_info * ci,struct romconfig * rc)601 int add_scsi_device(struct scsi_data **sd, int ch, struct uaedev_config_info *ci, struct romconfig *rc)
602 {
603 if (ci->type == UAEDEV_CD)
604 return add_scsi_cd(sd, ch, ci->device_emu_unit);
605 else if (ci->type == UAEDEV_TAPE)
606 return add_scsi_tape(sd, ch, ci->rootdir, ci->readonly);
607 else if (ci->type == UAEDEV_HDF)
608 return add_scsi_hd(sd, ch, NULL, ci);
609 return 0;
610 }
611
scsi_freenative(struct scsi_data ** sd,int max)612 void scsi_freenative(struct scsi_data **sd, int max)
613 {
614 for (int i = 0; i < max; i++) {
615 free_scsi (sd[i]);
616 sd[i] = NULL;
617 }
618 }
619
scsi_addnative(struct scsi_data ** sd)620 void scsi_addnative(struct scsi_data **sd)
621 {
622 int i, j;
623 int devices[MAX_TOTAL_SCSI_DEVICES];
624 int types[MAX_TOTAL_SCSI_DEVICES];
625 struct device_info dis[MAX_TOTAL_SCSI_DEVICES];
626
627 scsi_freenative (sd, MAX_TOTAL_SCSI_DEVICES);
628 i = 0;
629 while (i < MAX_TOTAL_SCSI_DEVICES) {
630 types[i] = -1;
631 devices[i] = -1;
632 if (sys_command_open (i)) {
633 if (sys_command_info (i, &dis[i], 0)) {
634 devices[i] = i;
635 types[i] = 100 - i;
636 if (dis[i].type == INQ_ROMD)
637 types[i] = 1000 - i;
638 }
639 sys_command_close (i);
640 }
641 i++;
642 }
643 i = 0;
644 while (devices[i] >= 0) {
645 j = i + 1;
646 while (devices[j] >= 0) {
647 if (types[i] > types[j]) {
648 int tmp = types[i];
649 types[i] = types[j];
650 types[j] = tmp;
651 }
652 j++;
653 }
654 i++;
655 }
656 i = 0; j = 0;
657 while (devices[i] >= 0 && j < 7) {
658 if (sd[j] == NULL) {
659 sd[j] = scsi_alloc_native(j, devices[i]);
660 write_log (_T("SCSI: %d:'%s'\n"), j, dis[i].label);
661 i++;
662 }
663 j++;
664 }
665 }
666
667 // raw scsi
668
669 #define SCSI_IO_BUSY 0x80
670 #define SCSI_IO_ATN 0x40
671 #define SCSI_IO_SEL 0x20
672 #define SCSI_IO_REQ 0x10
673 #define SCSI_IO_DIRECTION 0x01
674 #define SCSI_IO_COMMAND 0x02
675 #define SCSI_IO_MESSAGE 0x04
676
677 #define SCSI_SIGNAL_PHASE_FREE -1
678 #define SCSI_SIGNAL_PHASE_ARBIT -2
679 #define SCSI_SIGNAL_PHASE_SELECT_1 -3
680 #define SCSI_SIGNAL_PHASE_SELECT_2 -4
681
682 #define SCSI_SIGNAL_PHASE_DATA_OUT 0
683 #define SCSI_SIGNAL_PHASE_DATA_IN 1
684 #define SCSI_SIGNAL_PHASE_COMMAND 2
685 #define SCSI_SIGNAL_PHASE_STATUS 3
686 #define SCSI_SIGNAL_PHASE_MESSAGE_OUT 6
687 #define SCSI_SIGNAL_PHASE_MESSAGE_IN 7
688
689 struct raw_scsi
690 {
691 int io;
692 int bus_phase;
693 bool atn;
694 bool ack;
695 bool wait_ack;
696 uae_u8 data_write;
697 uae_u8 status;
698 bool databusoutput;
699 int initiator_id, target_id;
700 struct scsi_data *device[MAX_TOTAL_SCSI_DEVICES];
701 struct scsi_data *target;
702 int msglun;
703 };
704
705 struct soft_scsi
706 {
707 uae_u8 regs[8 + 1];
708 uae_u8 regs_400[2];
709 int c400_count;
710 struct raw_scsi rscsi;
711 bool irq;
712 bool intena;
713 bool level6;
714 bool enabled;
715 bool delayed_irq;
716 bool configured;
717 uae_u8 acmemory[128];
718 uaecptr baseaddress;
719 uaecptr baseaddress2;
720 uae_u8 *rom;
721 int rom_size;
722 int board_mask;
723 int board_size;
724 addrbank *bank;
725 int type;
726 int subtype;
727 int dma_direction;
728 bool dma_active;
729 bool dma_controller;
730 struct romconfig *rc;
731 struct soft_scsi **self_ptr;
732
733 int dmac_direction;
734 uaecptr dmac_address;
735 int dmac_length;
736 int dmac_active;
737 int chip_state;
738
739 // add500
740 uae_u16 databuffer[2];
741 bool databuffer_empty;
742
743 // kronos
744 uae_u8 *databufferptr;
745 int databuffer_size;
746 int db_read_index;
747 int db_write_index;
748
749 // sasi
750 bool active_select;
751 bool wait_select;
752 };
753
754
755 #define MAX_SOFT_SCSI_UNITS 10
756 static struct soft_scsi *soft_scsi_devices[MAX_SOFT_SCSI_UNITS];
757 static struct soft_scsi *soft_scsi_units[NCR_LAST * MAX_DUPLICATE_EXPANSION_BOARDS];
758 bool parallel_port_scsi;
759 static struct soft_scsi *parallel_port_scsi_data;
760 static struct soft_scsi *x86_hd_data;
761
soft_scsi_free_unit(struct soft_scsi * s)762 static void soft_scsi_free_unit(struct soft_scsi *s)
763 {
764 if (!s)
765 return;
766 struct raw_scsi *rs = &s->rscsi;
767 for (int j = 0; j < 8; j++) {
768 free_scsi (rs->device[j]);
769 rs->device[j] = NULL;
770 }
771 xfree(s->databufferptr);
772 xfree(s->rom);
773 if (s->self_ptr)
774 *s->self_ptr = NULL;
775 xfree(s);
776 }
777
freescsi(struct soft_scsi ** ncr)778 static void freescsi(struct soft_scsi **ncr)
779 {
780 if (!ncr)
781 return;
782 for (int i = 0; i < MAX_SOFT_SCSI_UNITS; i++) {
783 if (soft_scsi_devices[i] == *ncr) {
784 soft_scsi_devices[i] = NULL;
785 }
786 }
787 if (*ncr) {
788 soft_scsi_free_unit(*ncr);
789 }
790 *ncr = NULL;
791 }
792
allocscsi(struct soft_scsi ** ncr,struct romconfig * rc,int ch)793 static struct soft_scsi *allocscsi(struct soft_scsi **ncr, struct romconfig *rc, int ch)
794 {
795 struct soft_scsi *scsi;
796
797 if (ch < 0) {
798 freescsi(ncr);
799 *ncr = NULL;
800 }
801 if ((*ncr) == NULL) {
802 scsi = xcalloc(struct soft_scsi, 1);
803 for (int i = 0; i < MAX_SOFT_SCSI_UNITS; i++) {
804 if (soft_scsi_devices[i] == NULL) {
805 soft_scsi_devices[i] = scsi;
806 rc->unitdata = scsi;
807 scsi->rc = rc;
808 scsi->self_ptr = ncr;
809 if (ncr)
810 *ncr = scsi;
811 return scsi;
812 }
813 }
814 }
815 return *ncr;
816 }
817
getscsi(struct romconfig * rc)818 static struct soft_scsi *getscsi(struct romconfig *rc)
819 {
820 if (rc->unitdata)
821 return (struct soft_scsi*)rc->unitdata;
822 return NULL;
823 }
824
825
getscsiboard(uaecptr addr)826 static struct soft_scsi *getscsiboard(uaecptr addr)
827 {
828 for (int i = 0; soft_scsi_devices[i]; i++) {
829 struct soft_scsi *s = soft_scsi_devices[i];
830 if (!s->baseaddress && !s->configured)
831 return s;
832 if ((addr & ~s->board_mask) == s->baseaddress)
833 return s;
834 if (s->baseaddress2 && (addr & ~s->board_mask) == s->baseaddress2)
835 return s;
836 if (s->baseaddress == 0xe80000 && addr < 65536)
837 return s;
838 }
839 return NULL;
840 }
841
raw_scsi_reset(struct raw_scsi * rs)842 static void raw_scsi_reset(struct raw_scsi *rs)
843 {
844 rs->target = NULL;
845 rs->io = 0;
846 rs->bus_phase = SCSI_SIGNAL_PHASE_FREE;
847 }
848
849 extern addrbank soft_bank_generic;
850
ew(struct soft_scsi * scsi,int addr,uae_u32 value)851 static void ew(struct soft_scsi *scsi, int addr, uae_u32 value)
852 {
853 addr &= 0xffff;
854 if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
855 scsi->acmemory[addr] = (value & 0xf0);
856 scsi->acmemory[addr + 2] = (value & 0x0f) << 4;
857 } else {
858 scsi->acmemory[addr] = ~(value & 0xf0);
859 scsi->acmemory[addr + 2] = ~((value & 0x0f) << 4);
860 }
861 }
862
generic_soft_scsi_add(int ch,struct uaedev_config_info * ci,struct romconfig * rc,int type,int boardsize,int romsize,int romtype)863 static void generic_soft_scsi_add(int ch, struct uaedev_config_info *ci, struct romconfig *rc, int type, int boardsize, int romsize, int romtype)
864 {
865 struct soft_scsi *ss = allocscsi(&soft_scsi_units[type * MAX_DUPLICATE_EXPANSION_BOARDS + ci->controller_type_unit], rc, ch);
866 ss->type = type;
867 ss->configured = 0;
868 ss->bank = &soft_bank_generic;
869 ss->subtype = rc->subtype;
870 ss->intena = false;
871 if (boardsize > 0) {
872 ss->board_size = boardsize;
873 ss->board_mask = ss->board_size - 1;
874 }
875 if (!ss->board_mask && !ss->board_size) {
876 ss->board_size = 0x10000;
877 ss->board_mask = 0xffff;
878 }
879 if (romsize >= 0) {
880 ss->rom_size = romsize;
881 xfree(ss->rom);
882 ss->rom = NULL;
883 if (romsize > 0) {
884 ss->rom = xcalloc(uae_u8, ss->rom_size);
885 memset(ss->rom, 0xff, ss->rom_size);
886 }
887 }
888 memset(ss->acmemory, 0xff, sizeof ss->acmemory);
889 const struct expansionromtype *ert = get_device_expansion_rom(romtype);
890 if (ert) {
891 const uae_u8 *ac = NULL;
892 if (ert->subtypes)
893 ac = ert->subtypes[rc->subtype].autoconfig;
894 else
895 ac = ert->autoconfig;
896 if (ac[0]) {
897 for (int i = 0; i < 16; i++) {
898 uae_u8 b = ac[i];
899 ew(ss, i * 4, b);
900 }
901 }
902 }
903 raw_scsi_reset(&ss->rscsi);
904 if (ch < 0)
905 return;
906 add_scsi_device(&ss->rscsi.device[ch], ch, ci, rc);
907 }
908
raw_scsi_busfree(struct raw_scsi * rs)909 static void raw_scsi_busfree(struct raw_scsi *rs)
910 {
911 rs->target = NULL;
912 rs->io = 0;
913 rs->bus_phase = SCSI_SIGNAL_PHASE_FREE;
914 }
915
bus_free(struct raw_scsi * rs)916 static void bus_free(struct raw_scsi *rs)
917 {
918 rs->bus_phase = SCSI_SIGNAL_PHASE_FREE;
919 rs->io = 0;
920 }
921
getbit(uae_u8 v)922 static int getbit(uae_u8 v)
923 {
924 for (int i = 7; i >= 0; i--) {
925 if ((1 << i) & v)
926 return i;
927 }
928 return -1;
929 }
countbits(uae_u8 v)930 static int countbits(uae_u8 v)
931 {
932 int cnt = 0;
933 for (int i = 7; i >= 0; i--) {
934 if ((1 << i) & v)
935 cnt++;
936 }
937 return cnt;
938 }
939
raw_scsi_reset_bus(struct soft_scsi * scsi)940 static void raw_scsi_reset_bus(struct soft_scsi *scsi)
941 {
942 struct raw_scsi *r = &scsi->rscsi;
943 #if RAW_SCSI_DEBUG
944 write_log(_T("SCSI BUS reset\n"));
945 #endif
946 for (int i = 0; i < 8; i++) {
947 scsi_emulate_reset_device(r->device[i]);
948 }
949 }
950
951
raw_scsi_set_databus(struct raw_scsi * rs,bool databusoutput)952 static void raw_scsi_set_databus(struct raw_scsi *rs, bool databusoutput)
953 {
954 rs->databusoutput = databusoutput;
955 }
956
raw_scsi_set_signal_phase(struct raw_scsi * rs,bool busy,bool select,bool atn)957 static void raw_scsi_set_signal_phase(struct raw_scsi *rs, bool busy, bool select, bool atn)
958 {
959 switch (rs->bus_phase)
960 {
961 case SCSI_SIGNAL_PHASE_FREE:
962 if (busy && !select && !rs->databusoutput) {
963 if (countbits(rs->data_write) != 1) {
964 #if RAW_SCSI_DEBUG
965 write_log(_T("raw_scsi: invalid arbitration scsi id mask! (%02x)\n"), rs->data_write);
966 #endif
967 return;
968 }
969 rs->bus_phase = SCSI_SIGNAL_PHASE_ARBIT;
970 rs->initiator_id = getbit(rs->data_write);
971 #if RAW_SCSI_DEBUG
972 write_log(_T("raw_scsi: arbitration initiator id %d (%02x)\n"), rs->initiator_id, rs->data_write);
973 #endif
974 } else if (!busy && select) {
975 if (countbits(rs->data_write) > 2 || rs->data_write == 0) {
976 #if RAW_SCSI_DEBUG
977 write_log(_T("raw_scsi: invalid scsi id selected mask (%02x)\n"), rs->data_write);
978 #endif
979 return;
980 }
981 rs->initiator_id = -1;
982 rs->bus_phase = SCSI_SIGNAL_PHASE_SELECT_1;
983 #if RAW_SCSI_DEBUG
984 write_log(_T("raw_scsi: selected scsi id mask (%02x)\n"), rs->data_write);
985 #endif
986 raw_scsi_set_signal_phase(rs, busy, select, atn);
987 }
988 break;
989 case SCSI_SIGNAL_PHASE_ARBIT:
990 rs->target_id = -1;
991 rs->target = NULL;
992 if (busy && select) {
993 rs->bus_phase = SCSI_SIGNAL_PHASE_SELECT_1;
994 }
995 break;
996 case SCSI_SIGNAL_PHASE_SELECT_1:
997 rs->atn = atn;
998 rs->msglun = -1;
999 rs->target_id = -1;
1000 if (!busy) {
1001 for (int i = 0; i < 8; i++) {
1002 if (i == rs->initiator_id)
1003 continue;
1004 if ((rs->data_write & (1 << i)) && rs->device[i]) {
1005 rs->target_id = i;
1006 rs->target = rs->device[rs->target_id];
1007 #if RAW_SCSI_DEBUG
1008 write_log(_T("raw_scsi: selected id %d\n"), rs->target_id);
1009 #endif
1010 rs->io |= SCSI_IO_BUSY;
1011 }
1012 }
1013 #if RAW_SCSI_DEBUG
1014 if (rs->target_id < 0) {
1015 for (int i = 0; i < 8; i++) {
1016 if (i == rs->initiator_id)
1017 continue;
1018 if ((rs->data_write & (1 << i)) && !rs->device[i]) {
1019 write_log(_T("raw_scsi: selected non-existing id %d\n"), i);
1020 }
1021 }
1022 }
1023 #endif
1024 if (rs->target_id >= 0) {
1025 rs->bus_phase = SCSI_SIGNAL_PHASE_SELECT_2;
1026 } else {
1027 if (!select) {
1028 rs->bus_phase = SCSI_SIGNAL_PHASE_FREE;
1029 }
1030 }
1031 }
1032 break;
1033 case SCSI_SIGNAL_PHASE_SELECT_2:
1034 if (!select) {
1035 scsi_start_transfer(rs->target);
1036 rs->bus_phase = rs->atn ? SCSI_SIGNAL_PHASE_MESSAGE_OUT : SCSI_SIGNAL_PHASE_COMMAND;
1037 rs->io = SCSI_IO_BUSY | SCSI_IO_REQ;
1038 }
1039 break;
1040 }
1041 }
1042
raw_scsi_get_signal_phase(struct raw_scsi * rs)1043 static uae_u8 raw_scsi_get_signal_phase(struct raw_scsi *rs)
1044 {
1045 uae_u8 v = rs->io;
1046 if (rs->bus_phase >= 0)
1047 v |= rs->bus_phase;
1048 if (rs->ack)
1049 v &= ~SCSI_IO_REQ;
1050 return v;
1051 }
1052
raw_scsi_get_data_2(struct raw_scsi * rs,bool next,bool nodebug)1053 static uae_u8 raw_scsi_get_data_2(struct raw_scsi *rs, bool next, bool nodebug)
1054 {
1055 struct scsi_data *sd = rs->target;
1056 uae_u8 v = 0;
1057
1058 switch (rs->bus_phase)
1059 {
1060 case SCSI_SIGNAL_PHASE_FREE:
1061 v = 0;
1062 break;
1063 case SCSI_SIGNAL_PHASE_ARBIT:
1064 #if RAW_SCSI_DEBUG
1065 write_log(_T("raw_scsi: arbitration\n"));
1066 #endif
1067 v = rs->data_write;
1068 break;
1069 case SCSI_SIGNAL_PHASE_DATA_IN:
1070 #if RAW_SCSI_DEBUG > 2
1071 scsi_receive_data(sd, &v, false);
1072 write_log(_T("raw_scsi: read data byte %02x (%d/%d)\n"), v, sd->offset, sd->data_len);
1073 #endif
1074 if (scsi_receive_data(sd, &v, next)) {
1075 write_log(_T("raw_scsi: data in finished, %d bytes: status phase\n"), sd->offset);
1076 rs->bus_phase = SCSI_SIGNAL_PHASE_STATUS;
1077 }
1078 break;
1079 case SCSI_SIGNAL_PHASE_STATUS:
1080 #if RAW_SCSI_DEBUG
1081 if (!nodebug)
1082 write_log(_T("raw_scsi: status byte read %02x\n"), sd->status);
1083 #endif
1084 v = sd->status;
1085 if (next) {
1086 sd->status = 0;
1087 rs->bus_phase = SCSI_SIGNAL_PHASE_MESSAGE_IN;
1088 }
1089 break;
1090 case SCSI_SIGNAL_PHASE_MESSAGE_IN:
1091 #if RAW_SCSI_DEBUG
1092 if (!nodebug)
1093 write_log(_T("raw_scsi: message byte read %02x\n"), sd->status);
1094 #endif
1095 v = sd->status;
1096 rs->status = v;
1097 if (next) {
1098 bus_free(rs);
1099 }
1100 break;
1101 default:
1102 write_log(_T("raw_scsi_get_data but bus phase is %d!\n"), rs->bus_phase);
1103 break;
1104 }
1105
1106 return v;
1107 }
1108
raw_scsi_get_data(struct raw_scsi * rs,bool next)1109 static uae_u8 raw_scsi_get_data(struct raw_scsi *rs, bool next)
1110 {
1111 return raw_scsi_get_data_2(rs, next, true);
1112 }
1113
1114
getmsglen(uae_u8 * msgp,int len)1115 static int getmsglen(uae_u8 *msgp, int len)
1116 {
1117 uae_u8 msg = msgp[0];
1118 if (msg == 0 || (msg >= 0x02 && msg <= 0x1f) ||msg >= 0x80)
1119 return 1;
1120 if (msg >= 0x02 && msg <= 0x1f)
1121 return 2;
1122 if (msg >= 0x20 && msg <= 0x2f)
1123 return 3;
1124 // extended message, at least 3 bytes
1125 if (len < 2)
1126 return 3;
1127 return msgp[1];
1128 }
1129
raw_scsi_write_data(struct raw_scsi * rs,uae_u8 data)1130 static void raw_scsi_write_data(struct raw_scsi *rs, uae_u8 data)
1131 {
1132 struct scsi_data *sd = rs->target;
1133 int len;
1134
1135 switch (rs->bus_phase)
1136 {
1137 case SCSI_SIGNAL_PHASE_SELECT_1:
1138 case SCSI_SIGNAL_PHASE_FREE:
1139 break;
1140 case SCSI_SIGNAL_PHASE_COMMAND:
1141 sd->cmd[sd->offset++] = data;
1142 len = scsicmdsizes[sd->cmd[0] >> 5];
1143 #if RAW_SCSI_DEBUG > 1
1144 write_log(_T("raw_scsi: got command byte %02x (%d/%d)\n"), data, sd->offset, len);
1145 #endif
1146 if (sd->offset >= len) {
1147 if (rs->msglun >= 0) {
1148 sd->cmd[1] &= ~(0x80 | 0x40 | 0x20);
1149 sd->cmd[1] |= rs->msglun << 5;
1150 }
1151 scsi_emulate_analyze(rs->target);
1152 if (sd->direction > 0) {
1153 #if RAW_SCSI_DEBUG
1154 write_log(_T("raw_scsi: data out %d bytes required\n"), sd->data_len);
1155 #endif
1156 scsi_start_transfer(sd);
1157 rs->bus_phase = SCSI_SIGNAL_PHASE_DATA_OUT;
1158 } else if (sd->direction <= 0) {
1159 scsi_emulate_cmd(sd);
1160 scsi_start_transfer(sd);
1161 if (!sd->status && sd->data_len > 0) {
1162 #if RAW_SCSI_DEBUG
1163 write_log(_T("raw_scsi: data in %d bytes waiting\n"), sd->data_len);
1164 #endif
1165 rs->bus_phase = SCSI_SIGNAL_PHASE_DATA_IN;
1166 } else {
1167 #if RAW_SCSI_DEBUG
1168 write_log(_T("raw_scsi: no data, status = %d\n"), sd->status);
1169 #endif
1170 rs->bus_phase = SCSI_SIGNAL_PHASE_STATUS;
1171 }
1172 }
1173 }
1174 break;
1175 case SCSI_SIGNAL_PHASE_DATA_OUT:
1176 #if RAW_SCSI_DEBUG > 2
1177 write_log(_T("raw_scsi: write data byte %02x (%d/%d)\n"), data, sd->offset, sd->data_len);
1178 #endif
1179 if (scsi_send_data(sd, data)) {
1180 #if RAW_SCSI_DEBUG
1181 write_log(_T("raw_scsi: data out finished, %d bytes\n"), sd->data_len);
1182 #endif
1183 scsi_emulate_cmd(sd);
1184 rs->bus_phase = SCSI_SIGNAL_PHASE_STATUS;
1185 }
1186 break;
1187 case SCSI_SIGNAL_PHASE_MESSAGE_OUT:
1188 sd->msgout[sd->offset++] = data;
1189 len = getmsglen(sd->msgout, sd->offset);
1190 write_log(_T("raw_scsi_put_data got message %02x (%d/%d)\n"), data, sd->offset, len);
1191 if (sd->offset >= len) {
1192 write_log(_T("raw_scsi_put_data got message %02x (%d bytes)\n"), sd->msgout[0], len);
1193 if ((sd->msgout[0] & (0x80 | 0x20)) == 0x80)
1194 rs->msglun = sd->msgout[0] & 7;
1195 scsi_start_transfer(sd);
1196 rs->bus_phase = SCSI_SIGNAL_PHASE_COMMAND;
1197 }
1198 break;
1199 default:
1200 write_log(_T("raw_scsi_put_data but bus phase is %d!\n"), rs->bus_phase);
1201 break;
1202 }
1203 }
1204
raw_scsi_put_data(struct raw_scsi * rs,uae_u8 data,bool databusoutput)1205 static void raw_scsi_put_data(struct raw_scsi *rs, uae_u8 data, bool databusoutput)
1206 {
1207 rs->data_write = data;
1208 if (!databusoutput)
1209 return;
1210 raw_scsi_write_data(rs, data);
1211 }
1212
raw_scsi_set_ack(struct raw_scsi * rs,bool ack)1213 static void raw_scsi_set_ack(struct raw_scsi *rs, bool ack)
1214 {
1215 if (rs->ack != ack) {
1216 rs->ack = ack;
1217 if (!ack)
1218 return;
1219 if (rs->bus_phase < 0)
1220 return;
1221 if (!(rs->bus_phase & SCSI_IO_DIRECTION)) {
1222 if (rs->databusoutput) {
1223 raw_scsi_write_data(rs, rs->data_write);
1224 }
1225 } else {
1226 raw_scsi_get_data_2(rs, true, false);
1227 }
1228 }
1229 }
1230
1231 // APOLLO SOFTSCSI
1232
apollo_scsi_bput(uaecptr addr,uae_u8 v)1233 void apollo_scsi_bput(uaecptr addr, uae_u8 v)
1234 {
1235 struct soft_scsi *as = getscsiboard(addr);
1236 if (!as)
1237 return;
1238 int bank = addr & (0x800 | 0x400);
1239 struct raw_scsi *rs = &as->rscsi;
1240 addr &= 0x3fff;
1241 if (bank == 0) {
1242 raw_scsi_put_data(rs, v, true);
1243 } else if (bank == 0xc00 && !(addr & 1)) {
1244 as->irq = (v & 64) != 0;
1245 raw_scsi_set_signal_phase(rs,
1246 (v & 128) != 0,
1247 (v & 32) != 0,
1248 false);
1249 } else if (bank == 0x400 && (addr & 1)) {
1250 raw_scsi_put_data(rs, v, true);
1251 raw_scsi_set_signal_phase(rs, true, false, false);
1252 }
1253 //write_log(_T("apollo scsi put %04x = %02x\n"), addr, v);
1254 }
1255
apollo_scsi_bget(uaecptr addr)1256 uae_u8 apollo_scsi_bget(uaecptr addr)
1257 {
1258 struct soft_scsi *as = getscsiboard(addr);
1259 if (!as)
1260 return 0;
1261 int bank = addr & (0x800 | 0x400);
1262 struct raw_scsi *rs = &as->rscsi;
1263 uae_u8 v = 0xff;
1264 addr &= 0x3fff;
1265 if (bank == 0) {
1266 v = raw_scsi_get_data(rs, true);
1267 } else if (bank == 0x800 && (addr & 1)) {
1268 uae_u8 t = raw_scsi_get_signal_phase(rs);
1269 v = 1; // disable switch off
1270 if (t & SCSI_IO_BUSY)
1271 v |= 128;
1272 if (t & SCSI_IO_SEL)
1273 v |= 32;
1274 if (t & SCSI_IO_REQ)
1275 v |= 2;
1276 if (t & SCSI_IO_DIRECTION)
1277 v |= 8;
1278 if (t & SCSI_IO_COMMAND)
1279 v |= 16;
1280 if (t & SCSI_IO_MESSAGE)
1281 v |= 4;
1282 v ^= (1 | 2 | 4 | 8 | 16 | 32 | 128);
1283 //v |= apolloscsi.irq ? 64 : 0;
1284 }
1285 //write_log(_T("apollo scsi get %04x = %02x\n"), addr, v);
1286 return v;
1287 }
1288
1289 void apollo_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
1290
apollo_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1291 void apollo_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1292 {
1293 if (ch < 0) {
1294 generic_soft_scsi_add(-1, ci, rc, NONCR_APOLLO, -1, -1, ROMTYPE_APOLLO);
1295 // make sure IDE side is also initialized
1296 struct uaedev_config_info ci2 = { 0 };
1297 apollo_add_ide_unit(-1, &ci2, rc);
1298 } else {
1299 if (ci->controller_type < HD_CONTROLLER_TYPE_SCSI_FIRST) {
1300 apollo_add_ide_unit(ch, ci, rc);
1301 } else {
1302 generic_soft_scsi_add(ch, ci, rc, NONCR_APOLLO, -1, -1, ROMTYPE_APOLLO);
1303 }
1304 }
1305 }
1306
1307 uae_u8 ncr5380_bget(struct soft_scsi *scsi, int reg);
1308 void ncr5380_bput(struct soft_scsi *scsi, int reg, uae_u8 v);
1309
supra_do_dma(struct soft_scsi * ncr)1310 static void supra_do_dma(struct soft_scsi *ncr)
1311 {
1312 int len = ncr->dmac_length;
1313 for (int i = 0; i < len; i++) {
1314 if (ncr->dmac_direction < 0) {
1315 x_put_byte(ncr->dmac_address, ncr5380_bget(ncr, 0));
1316 } else if (ncr->dmac_direction > 0) {
1317 ncr5380_bput(ncr, 0, x_get_byte(ncr->dmac_address));
1318 }
1319 ncr->dmac_length--;
1320 ncr->dmac_address++;
1321 }
1322 }
1323
xebec_do_dma(struct soft_scsi * ncr)1324 static void xebec_do_dma(struct soft_scsi *ncr)
1325 {
1326 struct raw_scsi *rs = &ncr->rscsi;
1327 while (rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_OUT || rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_IN) {
1328 if (rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_IN) {
1329 x_put_byte(ncr->dmac_address, ncr5380_bget(ncr, 8));
1330 } else if (rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_OUT) {
1331 ncr5380_bput(ncr, 8, x_get_byte(ncr->dmac_address));
1332 }
1333 }
1334 }
1335
1336
dma_check(struct soft_scsi * ncr)1337 static void dma_check(struct soft_scsi *ncr)
1338 {
1339 if (ncr->dmac_active && ncr->dma_direction) {
1340
1341 if (ncr->type == NCR5380_SUPRA && ncr->subtype == 4) {
1342 if (ncr->dmac_direction != ncr->dma_direction) {
1343 write_log(_T("SUPRADMA: mismatched direction\n"));
1344 ncr->dmac_active = 0;
1345 return;
1346 }
1347 supra_do_dma(ncr);
1348 }
1349
1350 if (ncr->type == NCR5380_XEBEC) {
1351
1352 xebec_do_dma(ncr);
1353
1354 }
1355 ncr->dmac_active = 0;
1356 }
1357 }
1358
1359 // NCR 53C80/MISC SCSI-LIKE
1360
1361 void x86_doirq(uint8_t irqnum);
ncr80_rethink(void)1362 void ncr80_rethink(void)
1363 {
1364 for (int i = 0; soft_scsi_devices[i]; i++) {
1365 if (soft_scsi_devices[i]->irq && soft_scsi_devices[i]->intena) {
1366 if (soft_scsi_devices[i] == x86_hd_data) {
1367 x86_doirq(5);
1368 } else {
1369 if (soft_scsi_devices[i]->level6)
1370 INTREQ_0(0x8000 | 0x2000);
1371 else
1372 INTREQ_0(0x8000 | 0x0008);
1373 return;
1374 }
1375 }
1376 }
1377 }
1378
ncr5380_set_irq(struct soft_scsi * scsi)1379 static void ncr5380_set_irq(struct soft_scsi *scsi)
1380 {
1381 if (scsi->irq)
1382 return;
1383 scsi->irq = true;
1384 ncr80_rethink();
1385 if (scsi->delayed_irq)
1386 x_do_cycles(2 * CYCLE_UNIT);
1387 #if NCR5380_DEBUG_IRQ
1388 write_log(_T("IRQ\n"));
1389 #endif
1390 }
1391
ncr5380_databusoutput(struct soft_scsi * scsi)1392 static void ncr5380_databusoutput(struct soft_scsi *scsi)
1393 {
1394 bool databusoutput = (scsi->regs[1] & 1) != 0;
1395 struct raw_scsi *r = &scsi->rscsi;
1396
1397 if (r->bus_phase >= 0 && (r->bus_phase & SCSI_IO_DIRECTION))
1398 databusoutput = false;
1399 raw_scsi_set_databus(r, databusoutput);
1400 }
1401
ncr5380_check(struct soft_scsi * scsi)1402 static void ncr5380_check(struct soft_scsi *scsi)
1403 {
1404 ncr5380_databusoutput(scsi);
1405 }
1406
ncr5380_check_phase(struct soft_scsi * scsi)1407 static void ncr5380_check_phase(struct soft_scsi *scsi)
1408 {
1409 if (!(scsi->regs[2] & 2))
1410 return;
1411 if (scsi->regs[2] & 0x40)
1412 return;
1413 if (scsi->rscsi.bus_phase != (scsi->regs[3] & 7)) {
1414 if (scsi->dma_controller) {
1415 scsi->regs[5] |= 0x80; // end of dma
1416 scsi->regs[3] |= 0x80; // last byte sent
1417 }
1418 ncr5380_set_irq(scsi);
1419 }
1420 }
1421
ncr5380_reset(struct soft_scsi * scsi)1422 static void ncr5380_reset(struct soft_scsi *scsi)
1423 {
1424 struct raw_scsi *r = &scsi->rscsi;
1425
1426 scsi->irq = true;
1427 memset(scsi->regs, 0, sizeof scsi->regs);
1428 raw_scsi_reset_bus(scsi);
1429 scsi->regs[1] = 0x80;
1430 }
1431
ncr5380_bget(struct soft_scsi * scsi,int reg)1432 uae_u8 ncr5380_bget(struct soft_scsi *scsi, int reg)
1433 {
1434 if (reg > 8)
1435 return 0;
1436 uae_u8 v = scsi->regs[reg];
1437 struct raw_scsi *r = &scsi->rscsi;
1438 switch(reg)
1439 {
1440 case 1:
1441 break;
1442 case 4:
1443 {
1444 uae_u8 t = raw_scsi_get_signal_phase(r);
1445 v = 0;
1446 if (t & SCSI_IO_BUSY)
1447 v |= 1 << 6;
1448 if (t & SCSI_IO_REQ)
1449 v |= 1 << 5;
1450 if (t & SCSI_IO_SEL)
1451 v |= 1 << 1;
1452 if (r->bus_phase >= 0)
1453 v |= r->bus_phase << 2;
1454 if (scsi->regs[1] & 0x80)
1455 v |= 0x80;
1456 }
1457 break;
1458 case 5:
1459 {
1460 uae_u8 t = raw_scsi_get_signal_phase(r);
1461 v &= (0x80 | 0x40 | 0x20 | 0x04);
1462 if (t & SCSI_IO_ATN)
1463 v |= 1 << 1;
1464 if (r->bus_phase == (scsi->regs[3] & 7)) {
1465 v |= 1 << 3;
1466 }
1467 if (scsi->irq) {
1468 v |= 1 << 4;
1469 }
1470 if (scsi->dma_active && !scsi->dma_controller) {
1471 v |= 1 << 6;
1472 }
1473 if (scsi->regs[2] & 4) {
1474 // monitor busy
1475 if (r->bus_phase == SCSI_SIGNAL_PHASE_FREE) {
1476 // any loss of busy = Busy error
1477 // not just "unexpected" loss of busy
1478 v |= 1 << 2;
1479 scsi->dmac_active = false;
1480 }
1481 }
1482 }
1483 break;
1484 case 0:
1485 v = raw_scsi_get_data(r, false);
1486 break;
1487 case 6:
1488 v = raw_scsi_get_data(r, scsi->dma_active);
1489 ncr5380_check_phase(scsi);
1490 break;
1491 case 7:
1492 scsi->irq = false;
1493 break;
1494 case 8: // fake dma port
1495 v = raw_scsi_get_data(r, true);
1496 ncr5380_check_phase(scsi);
1497 break;
1498 }
1499 ncr5380_check(scsi);
1500 return v;
1501 }
1502
ncr5380_bput(struct soft_scsi * scsi,int reg,uae_u8 v)1503 void ncr5380_bput(struct soft_scsi *scsi, int reg, uae_u8 v)
1504 {
1505 if (reg > 8)
1506 return;
1507 bool dataoutput = (scsi->regs[1] & 1) != 0;
1508 struct raw_scsi *r = &scsi->rscsi;
1509 uae_u8 old = scsi->regs[reg];
1510 scsi->regs[reg] = v;
1511 switch(reg)
1512 {
1513 case 0:
1514 {
1515 r->data_write = v;
1516 // assert data bus can be only active if direction is out
1517 // and bus phase matches
1518 if (r->databusoutput) {
1519 if (((scsi->regs[2] & 2) && scsi->dma_active) || r->bus_phase < 0) {
1520 raw_scsi_write_data(r, v);
1521 ncr5380_check_phase(scsi);
1522 }
1523 }
1524 }
1525 break;
1526 case 1:
1527 {
1528 scsi->regs[reg] &= ~((1 << 5) | (1 << 6));
1529 scsi->regs[reg] |= old & ((1 << 5) | (1 << 6)); // AIP, LA
1530 if (!(v & 0x80)) {
1531 bool init = r->bus_phase < 0;
1532 ncr5380_databusoutput(scsi);
1533 if (init && !dataoutput && (v & 1) && (scsi->regs[2] & 1)) {
1534 r->bus_phase = SCSI_SIGNAL_PHASE_SELECT_1;
1535 }
1536 raw_scsi_set_signal_phase(r,
1537 (v & (1 << 3)) != 0,
1538 (v & (1 << 2)) != 0,
1539 (v & (1 << 1)) != 0);
1540 if (!(scsi->regs[2] & 2))
1541 raw_scsi_set_ack(r, (v & (1 << 4)) != 0);
1542 }
1543 if (v & 0x80) { // RST
1544 ncr5380_reset(scsi);
1545 }
1546 }
1547 break;
1548 case 2:
1549 if ((v & 1) && !(old & 1)) { // Arbitrate
1550 r->databusoutput = false;
1551 raw_scsi_set_signal_phase(r, true, false, false);
1552 scsi->regs[1] |= 1 << 6; // AIP
1553 scsi->regs[1] &= ~(1 << 5); // LA
1554 } else if (!(v & 1) && (old & 1)) {
1555 scsi->regs[1] &= ~(1 << 6);
1556 }
1557 if (!(v & 2)) {
1558 // end of dma and dma request
1559 scsi->regs[5] &= ~(0x80 | 0x40);
1560 scsi->dma_direction = 0;
1561 scsi->dma_active = false;
1562 }
1563 break;
1564 case 5:
1565 scsi->regs[reg] = old;
1566 if (scsi->regs[2] & 2) {
1567 scsi->dma_direction = 1;
1568 scsi->dma_active = true;
1569 dma_check(scsi);
1570 }
1571 #if NCR5380_DEBUG
1572 write_log(_T("DMA send PC=%08x\n"), M68K_GETPC);
1573 #endif
1574 break;
1575 case 6:
1576 if (scsi->regs[2] & 2) {
1577 scsi->dma_direction = 1;
1578 scsi->dma_active = true;
1579 }
1580 #if NCR5380_DEBUG
1581 write_log(_T("DMA target recv PC=%08x\n"), M68K_GETPC);
1582 #endif
1583 break;
1584 case 7:
1585 if (scsi->regs[2] & 2) {
1586 scsi->dma_direction = -1;
1587 scsi->dma_active = true;
1588 dma_check(scsi);
1589 }
1590 #if NCR5380_DEBUG
1591 write_log(_T("DMA initiator recv PC=%08x\n"), M68K_GETPC);
1592 #endif
1593 break;
1594 case 8: // fake dma port
1595 raw_scsi_put_data(r, v, true);
1596 ncr5380_check_phase(scsi);
1597 break;
1598 }
1599 ncr5380_check(scsi);
1600 }
1601
ncr53400_5380(struct soft_scsi * scsi)1602 static bool ncr53400_5380(struct soft_scsi *scsi)
1603 {
1604 if (scsi->irq)
1605 scsi->regs_400[1] = 0;
1606 return !scsi->regs_400[1];
1607 }
1608
ncr53400_dmacount(struct soft_scsi * scsi)1609 static void ncr53400_dmacount(struct soft_scsi *scsi)
1610 {
1611 scsi->c400_count++;
1612 if (scsi->c400_count == 128) {
1613 scsi->c400_count = 0;
1614 scsi->regs_400[1]--;
1615 if (scsi->regs_400[1] == 0) {
1616 scsi->regs[5] &= ~0x40; // dma request
1617 ncr5380_check_phase(scsi);
1618 }
1619 }
1620 }
1621
ncr53400_bget(struct soft_scsi * scsi,int reg)1622 static uae_u8 ncr53400_bget(struct soft_scsi *scsi, int reg)
1623 {
1624 struct raw_scsi *rs = &scsi->rscsi;
1625 uae_u8 v = 0;
1626 uae_u8 csr = scsi->regs_400[0];
1627
1628 if (ncr53400_5380(scsi) && reg < 8) {
1629 v = ncr5380_bget(scsi, reg);
1630 //write_log(_T("53C80 REG GET %02x -> %02x\n"), reg, v);
1631 return v;
1632 }
1633 if (reg & 0x80) {
1634 v = raw_scsi_get_data(rs, true);
1635 ncr53400_dmacount(scsi);
1636 } else if (reg & 0x100) {
1637 switch (reg) {
1638 case 0x100:
1639 if (scsi->regs_400[1]) {
1640 v |= 0x02;
1641 } else {
1642 v |= 0x04;
1643 }
1644 if (ncr53400_5380(scsi))
1645 v |= 0x80;
1646 if (scsi->irq)
1647 v |= 0x01;
1648 break;
1649 case 0x101:
1650 v = scsi->regs_400[1];
1651 break;
1652 }
1653 //write_log(_T("53C400 REG GET %02x -> %02x\n"), reg, v);
1654 }
1655 ncr5380_check_phase(scsi);
1656 return v;
1657 }
1658
ncr53400_bput(struct soft_scsi * scsi,int reg,uae_u8 v)1659 static void ncr53400_bput(struct soft_scsi *scsi, int reg, uae_u8 v)
1660 {
1661 struct raw_scsi *rs = &scsi->rscsi;
1662 uae_u8 csr = scsi->regs_400[0];
1663
1664 if (ncr53400_5380(scsi) && reg < 8) {
1665 ncr5380_bput(scsi, reg, v);
1666 //write_log(_T("53C80 REG PUT %02x -> %02x\n"), reg, v);
1667 return;
1668 }
1669 if (reg & 0x80) {
1670 raw_scsi_put_data(rs, v, true);
1671 ncr53400_dmacount(scsi);
1672 } else if (reg & 0x100) {
1673 switch (reg) {
1674 case 0x100:
1675 scsi->regs_400[0] = v;
1676 if (v & 0x80) {
1677 ncr5380_reset(scsi);
1678 scsi->regs_400[0] = 0x80;
1679 scsi->regs_400[1] = 0;
1680 }
1681 break;
1682 case 0x101:
1683 scsi->regs_400[1] = v;
1684 scsi->c400_count = 0;
1685 break;
1686 }
1687 //write_log(_T("53C400 REG PUT %02x -> %02x\n"), reg, v);
1688 }
1689 ncr5380_check_phase(scsi);
1690 }
1691
1692 /* SASI */
1693
sasi_tecmar_bget(struct soft_scsi * scsi,int reg)1694 static uae_u8 sasi_tecmar_bget(struct soft_scsi *scsi, int reg)
1695 {
1696 struct raw_scsi *rs = &scsi->rscsi;
1697 uae_u8 v = 0;
1698
1699 if (reg == 1) {
1700
1701 uae_u8 t = raw_scsi_get_signal_phase(rs);
1702 v = 0;
1703 switch (rs->bus_phase)
1704 {
1705 case SCSI_SIGNAL_PHASE_DATA_OUT:
1706 v = 0;
1707 break;
1708 case SCSI_SIGNAL_PHASE_DATA_IN:
1709 v = 1 << 2;
1710 break;
1711 case SCSI_SIGNAL_PHASE_COMMAND:
1712 v = 1 << 3;
1713 break;
1714 case SCSI_SIGNAL_PHASE_STATUS:
1715 v = (1 << 2) | (1 << 3);
1716 break;
1717 case SCSI_SIGNAL_PHASE_MESSAGE_IN:
1718 v = (1 << 2) | (1 << 3) | (1 << 4);
1719 break;
1720 }
1721 if (t & SCSI_IO_BUSY)
1722 v |= 1 << 1;
1723 if (t & SCSI_IO_REQ)
1724 v |= 1 << 0;
1725 v = v ^ 0xff;
1726
1727 } else {
1728
1729 v = raw_scsi_get_data_2(rs, true, false);
1730
1731 }
1732
1733 //write_log(_T("SASI READ port %d: %02x\n"), reg, v);
1734
1735 return v;
1736 }
1737
sasi_tecmar_bput(struct soft_scsi * scsi,int reg,uae_u8 v)1738 static void sasi_tecmar_bput(struct soft_scsi *scsi, int reg, uae_u8 v)
1739 {
1740 struct raw_scsi *rs = &scsi->rscsi;
1741
1742 //write_log(_T("SASI WRITE port %d: %02x\n"), reg, v);
1743
1744 if (reg == 1) {
1745 if ((v & 1)) {
1746 raw_scsi_busfree(rs);
1747 }
1748 if ((v & 2) && !scsi->active_select) {
1749 // select?
1750 scsi->active_select = true;
1751 if (!rs->data_write)
1752 scsi->wait_select = true;
1753 else
1754 raw_scsi_set_signal_phase(rs, false, true, false);
1755 } else if (!(v & 2) && scsi->active_select) {
1756 scsi->active_select = false;
1757 raw_scsi_set_signal_phase(rs, false, false, false);
1758 }
1759 } else {
1760 raw_scsi_put_data(rs, v, true);
1761 if (scsi->wait_select && scsi->active_select)
1762 raw_scsi_set_signal_phase(rs, false, true, false);
1763 scsi->wait_select = false;
1764 }
1765 }
1766
sasi_microforge_bget(struct soft_scsi * scsi,int reg)1767 static uae_u8 sasi_microforge_bget(struct soft_scsi *scsi, int reg)
1768 {
1769 struct raw_scsi *rs = &scsi->rscsi;
1770 uae_u8 v = 0;
1771
1772 if (reg == 1) {
1773
1774 uae_u8 t = raw_scsi_get_signal_phase(rs);
1775 v = 0;
1776 if (rs->bus_phase >= 0) {
1777 if (rs->bus_phase & SCSI_IO_MESSAGE)
1778 v |= 1 << 1;
1779 if (rs->bus_phase & SCSI_IO_COMMAND)
1780 v |= 1 << 2;
1781 if (rs->bus_phase & SCSI_IO_DIRECTION)
1782 v |= 1 << 3;
1783 }
1784 if (t & SCSI_IO_BUSY)
1785 v |= 1 << 0;
1786 if (t & SCSI_IO_REQ)
1787 v |= 1 << 4;
1788 v = v ^ 0xff;
1789
1790 } else {
1791
1792 v = raw_scsi_get_data_2(rs, true, false);
1793
1794 }
1795
1796 //write_log(_T("SASI READ port %d: %02x\n"), reg, v);
1797
1798 return v;
1799 }
1800
sasi_microforge_bput(struct soft_scsi * scsi,int reg,uae_u8 v)1801 static void sasi_microforge_bput(struct soft_scsi *scsi, int reg, uae_u8 v)
1802 {
1803 struct raw_scsi *rs = &scsi->rscsi;
1804
1805 //write_log(_T("SASI WRITE port %d: %02x\n"), reg, v);
1806
1807 if (reg == 1) {
1808 if ((v & 4) && !scsi->active_select) {
1809 // select?
1810 scsi->active_select = true;
1811 if (!rs->data_write)
1812 scsi->wait_select = true;
1813 else
1814 raw_scsi_set_signal_phase(rs, false, true, false);
1815 } else if (!(v & 4) && scsi->active_select) {
1816 scsi->active_select = false;
1817 raw_scsi_set_signal_phase(rs, false, false, false);
1818 }
1819 } else {
1820 raw_scsi_put_data(rs, v, true);
1821 if (scsi->wait_select && scsi->active_select)
1822 raw_scsi_set_signal_phase(rs, false, true, false);
1823 scsi->wait_select = false;
1824 }
1825 }
1826
1827 // OMTI 5510
omti_irq(struct soft_scsi * scsi)1828 static void omti_irq(struct soft_scsi *scsi)
1829 {
1830 if (scsi->intena && (scsi->chip_state & 2))
1831 ncr5380_set_irq(scsi);
1832 }
omti_check_state(struct soft_scsi * scsi)1833 static void omti_check_state(struct soft_scsi *scsi)
1834 {
1835 struct raw_scsi *rs = &scsi->rscsi;
1836 if ((rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_IN || rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_OUT) && (scsi->chip_state & 1)) {
1837 omti_irq(scsi);
1838 }
1839 }
1840
omti_bget(struct soft_scsi * scsi,int reg)1841 static uae_u8 omti_bget(struct soft_scsi *scsi, int reg)
1842 {
1843 struct raw_scsi *rs = &scsi->rscsi;
1844 uae_u8 t = raw_scsi_get_signal_phase(rs);
1845 uae_u8 v = 0;
1846
1847 switch (reg)
1848 {
1849 case 0: // DATA IN
1850 if (rs->bus_phase == SCSI_SIGNAL_PHASE_STATUS) {
1851 v = raw_scsi_get_data_2(rs, true, false);
1852 // get message (not used in OMTI protocol)
1853 raw_scsi_get_data_2(rs, true, false);
1854 } else {
1855 v = raw_scsi_get_data_2(rs, true, false);
1856 if (rs->bus_phase == SCSI_SIGNAL_PHASE_STATUS) {
1857 omti_irq(scsi); // command complete interrupt
1858 }
1859 }
1860 break;
1861 case 1: // STATUS
1862 if (rs->bus_phase >= 0)
1863 v |= 8; // busy
1864 if (v & 8) {
1865 if (t & SCSI_IO_REQ)
1866 v |= 1; // req
1867 if (t & SCSI_IO_DIRECTION)
1868 v |= 2;
1869 if (t & SCSI_IO_COMMAND)
1870 v |= 4;
1871 }
1872 v |= 0x80 | 0x40;
1873 if ((rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_IN || rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_OUT) && (scsi->chip_state & 1))
1874 v |= 0x10;
1875 if (scsi->irq)
1876 v |= 0x20;
1877 scsi->irq = false;
1878 break;
1879 break;
1880 case 2: // CONFIGURATION
1881 v = 0xff;
1882 break;
1883 case 3: // -
1884 break;
1885 }
1886 omti_check_state(scsi);
1887 return v;
1888 }
omti_bput(struct soft_scsi * scsi,int reg,uae_u8 v)1889 static void omti_bput(struct soft_scsi *scsi, int reg, uae_u8 v)
1890 {
1891 struct raw_scsi *rs = &scsi->rscsi;
1892 switch (reg)
1893 {
1894 case 0: // DATA OUT
1895 raw_scsi_put_data(rs, v, true);
1896 if (rs->bus_phase == SCSI_SIGNAL_PHASE_STATUS)
1897 omti_irq(scsi); // command complete interrupt
1898 break;
1899 case 1: // RESET
1900 raw_scsi_busfree(rs);
1901 scsi->chip_state = 0;
1902 break;
1903 case 2: // SELECT
1904 rs->data_write = 0x01;
1905 raw_scsi_set_signal_phase(rs, false, true, false);
1906 raw_scsi_set_signal_phase(rs, false, false, false);
1907 break;
1908 case 3: // MASK
1909 scsi->chip_state = v;
1910 break;
1911 }
1912 omti_check_state(scsi);
1913 }
1914
suprareg(struct soft_scsi * ncr,uaecptr addr,bool write)1915 static int suprareg(struct soft_scsi *ncr, uaecptr addr, bool write)
1916 {
1917 int reg = (addr & 0x0f) >> 1;
1918 if ((addr & 0x20) && ncr->subtype == 0) {
1919 // "dma" data in/out space
1920 reg = 8;
1921 if (!(ncr->regs[2] & 2))
1922 cpu_halt(CPU_HALT_FAKE_DMA);
1923 }
1924 return reg;
1925 }
1926
stardrivereg(struct soft_scsi * ncr,uaecptr addr)1927 static int stardrivereg(struct soft_scsi *ncr, uaecptr addr)
1928 {
1929 if ((addr & 0x0191) == 0x191) {
1930 // "dma" data in/out register
1931 return 8;
1932 }
1933 if ((addr & 0x0181) != 0x181)
1934 return -1;
1935 int reg = (addr >> 1) & 7;
1936 return reg;
1937 }
1938
cltdreg(struct soft_scsi * ncr,uaecptr addr)1939 static int cltdreg(struct soft_scsi *ncr, uaecptr addr)
1940 {
1941 if (!(addr & 1)) {
1942 return -1;
1943 }
1944 int reg = (addr >> 1) & 7;
1945 return reg;
1946 }
1947
protarreg(struct soft_scsi * ncr,uaecptr addr)1948 static int protarreg(struct soft_scsi *ncr, uaecptr addr)
1949 {
1950 int reg = -1;
1951 if ((addr & 0x24) == 0x20) {
1952 // "fake dma" data port
1953 reg = 8;
1954 } else if ((addr & 0x20) == 0x00) {
1955 reg = (addr >> 2) & 7;
1956 }
1957 return reg;
1958 }
1959
add500reg(struct soft_scsi * ncr,uaecptr addr)1960 static int add500reg(struct soft_scsi *ncr, uaecptr addr)
1961 {
1962 int reg = -1;
1963 if ((addr & 0x8048) == 0x8000) {
1964 reg = 8;
1965 } else if ((addr & 0x8040) == 0x8040) {
1966 reg = (addr >> 1) & 7;
1967 }
1968 return reg;
1969 }
1970
adscsireg(struct soft_scsi * ncr,uaecptr addr,bool write)1971 static int adscsireg(struct soft_scsi *ncr, uaecptr addr, bool write)
1972 {
1973 int reg = -1;
1974 if ((addr == 0x38 || addr == 0x39) && !write) {
1975 reg = 8;
1976 } else if ((addr == 0x20 || addr == 0x21) && write) {
1977 reg = 8;
1978 } else if (addr < 0x20) {
1979 reg = (addr >> 2) & 7;
1980 }
1981 return reg;
1982 }
1983
ptnexusreg(struct soft_scsi * ncr,uaecptr addr)1984 static int ptnexusreg(struct soft_scsi *ncr, uaecptr addr)
1985 {
1986 int reg = -1;
1987 if ((addr & 0x8ff0) == 0) {
1988 reg = (addr >> 1) & 7;
1989 }
1990 return reg;
1991 }
1992
xebec_reg(struct soft_scsi * ncr,uaecptr addr)1993 static int xebec_reg(struct soft_scsi *ncr, uaecptr addr)
1994 {
1995 if (addr < 0x10000) {
1996 if (addr & 1)
1997 return (addr & 0xff) >> 1;
1998 return -1;
1999 }
2000 if ((addr & 0x180000) == 0x100000) {
2001
2002 ncr->dmac_active = 1;
2003
2004 } else if ((addr & 0x180000) == 0x180000) {
2005
2006 ncr->dmac_active = 0;
2007 ncr->dmac_address = ncr->baseaddress | 0x80000;
2008
2009 } else if ((addr & 0x180000) == 0x080000) {
2010 ncr->dmac_address = addr | ncr->baseaddress | 1;
2011 ncr->dmac_address += 2;
2012 if (addr & 1)
2013 return 0x80000 + (addr & 32767);
2014 return -1;
2015 }
2016
2017 // if (addr >= 0x10000)
2018 // write_log(_T("XEBEC %08x PC=%08x\n"), addr, M68K_GETPC);
2019 return -1;
2020 }
2021
hda506_reg(struct soft_scsi * ncr,uaecptr addr,bool write)2022 static int hda506_reg(struct soft_scsi *ncr, uaecptr addr, bool write)
2023 {
2024 if ((addr & 0x7fe1) != 0x7fe0)
2025 return -1;
2026 addr &= 0x7;
2027 addr >>= 1;
2028 return addr;
2029 }
2030
alf1_reg(struct soft_scsi * ncr,uaecptr addr,bool write)2031 static int alf1_reg(struct soft_scsi *ncr, uaecptr addr, bool write)
2032 {
2033 if ((addr & 0x7ff9) != 0x0641)
2034 return -1;
2035 addr >>= 1;
2036 addr &= 3;
2037 return addr;
2038 }
2039
system2000_reg(struct soft_scsi * ncr,uaecptr addr,int size,bool write)2040 static int system2000_reg(struct soft_scsi *ncr, uaecptr addr, int size, bool write)
2041 {
2042 if (size != 1)
2043 return -1;
2044 if ((addr & 0xc007) != 0x4000)
2045 return -1;
2046 addr >>= 3;
2047 addr &= 3;
2048 return addr;
2049 }
2050
promigos_reg(struct soft_scsi * ncr,uaecptr addr,int size,bool write)2051 static int promigos_reg(struct soft_scsi *ncr, uaecptr addr, int size, bool write)
2052 {
2053 if (size != 1)
2054 return -1;
2055 if ((addr & 0x1) != 1)
2056 return -1;
2057 addr &= 7;
2058 if (addr == 1 && write)
2059 return 3;
2060 if (addr == 3 && write)
2061 return 0;
2062 if (addr == 5 && write)
2063 return 1;
2064 if (addr == 5 && !write)
2065 return 0;
2066 if (addr == 7 && write)
2067 return 2;
2068 if (addr == 7 && !write)
2069 return 1;
2070 return -1;
2071 }
2072
microforge_reg(struct soft_scsi * ncr,uaecptr addr,bool write)2073 static int microforge_reg(struct soft_scsi *ncr, uaecptr addr, bool write)
2074 {
2075 int reg = -1;
2076 if ((addr & 0x7000) != 0x7000)
2077 return -1;
2078 addr &= 0xfff;
2079 if (addr == 38 && !write)
2080 return 0;
2081 if (addr == 40 && write)
2082 return 0;
2083 if (addr == 42 && !write)
2084 return 1;
2085 if (addr == 44 && write)
2086 return 1;
2087 return reg;
2088 }
2089
phoenixboard_reg(struct soft_scsi * ncr,uaecptr addr)2090 static int phoenixboard_reg(struct soft_scsi *ncr, uaecptr addr)
2091 {
2092 if (addr & 1)
2093 return -1;
2094 if (addr & 0xc000)
2095 return -1;
2096 addr >>= 1;
2097 addr &= 7;
2098 return addr;
2099 }
2100
read_supra_dma(struct soft_scsi * ncr,uaecptr addr)2101 static uae_u8 read_supra_dma(struct soft_scsi *ncr, uaecptr addr)
2102 {
2103 uae_u8 val = 0;
2104
2105 addr &= 0x1f;
2106 switch (addr)
2107 {
2108 case 0:
2109 val = ncr->dmac_active ? 0x00 : 0x80;
2110 break;
2111 case 4:
2112 val = 0;
2113 break;
2114 }
2115
2116 write_log(_T("SUPRA DMA GET %08x %02x %08x\n"), addr, val, M68K_GETPC);
2117 return val;
2118 }
2119
write_supra_dma(struct soft_scsi * ncr,uaecptr addr,uae_u8 val)2120 static void write_supra_dma(struct soft_scsi *ncr, uaecptr addr, uae_u8 val)
2121 {
2122 write_log(_T("SUPRA DMA PUT %08x %02x %08x\n"), addr, val, M68K_GETPC);
2123
2124 addr &= 0x1f;
2125 switch (addr)
2126 {
2127 case 5: // OCR
2128 ncr->dmac_direction = (val & 0x80) ? -1 : 1;
2129 break;
2130 case 7:
2131 ncr->dmac_active = (val & 0x80) != 0;
2132 break;
2133 case 10: // MTCR
2134 ncr->dmac_length &= 0x000000ff;
2135 ncr->dmac_length |= val << 8;
2136 break;
2137 case 11: // MTCR
2138 ncr->dmac_length &= 0x0000ff00;
2139 ncr->dmac_length |= val << 0;
2140 break;
2141 case 12: // MAR
2142 break;
2143 case 13: // MAR
2144 ncr->dmac_address &= 0x0000ffff;
2145 ncr->dmac_address |= val << 16;
2146 break;
2147 case 14: // MAR
2148 ncr->dmac_address &= 0x00ff00ff;
2149 ncr->dmac_address |= val << 8;
2150 break;
2151 case 15: // MAR
2152 ncr->dmac_address &= 0x00ffff00;
2153 ncr->dmac_address |= val << 0;
2154 break;
2155 }
2156 }
2157
vector_scsi_status(struct raw_scsi * rs)2158 static void vector_scsi_status(struct raw_scsi *rs)
2159 {
2160 // Vector Falcon 8000 FPGA seems to handle this internally
2161 while (rs->bus_phase == SCSI_SIGNAL_PHASE_STATUS || rs->bus_phase == SCSI_SIGNAL_PHASE_MESSAGE_IN) {
2162 raw_scsi_get_data(rs, true);
2163 }
2164 }
2165
2166 static int tecmar_clock_reg_select;
2167 static uae_u8 tecmar_clock_regs[64];
tecmar_clock_bcd(uae_u8 v)2168 static uae_u8 tecmar_clock_bcd(uae_u8 v)
2169 {
2170 uae_u8 out = v;
2171 if (!(tecmar_clock_regs[11] & 4)) {
2172 out = ((v / 10) << 4) + (v % 10);
2173 }
2174 return out;
2175 }
tecmar_clock_bput(int addr,uae_u8 v)2176 static void tecmar_clock_bput(int addr, uae_u8 v)
2177 {
2178 if (addr == 0) {
2179 tecmar_clock_reg_select = v & 63;
2180 }
2181 else if (addr == 1) {
2182 tecmar_clock_regs[tecmar_clock_reg_select] = v;
2183 tecmar_clock_regs[12] = 0x00;
2184 tecmar_clock_regs[13] = 0x80;
2185 }
2186 }
tecmar_clock_bget(int addr)2187 static uae_u8 tecmar_clock_bget(int addr)
2188 {
2189 uae_u8 v = 0;
2190 if (addr == 0) {
2191 v = tecmar_clock_reg_select;
2192 }
2193 else if (addr == 1) {
2194 time_t t = time(0);
2195 t += currprefs.cs_rtc_adjust;
2196 struct tm *ct = localtime(&t);
2197 switch (tecmar_clock_reg_select)
2198 {
2199 case 0:
2200 v = tecmar_clock_bcd(ct->tm_sec);
2201 break;
2202 case 2:
2203 v = tecmar_clock_bcd(ct->tm_min);
2204 break;
2205 case 4:
2206 v = tecmar_clock_bcd(ct->tm_hour);
2207 if (!(tecmar_clock_regs[11] & 2)) {
2208 if (v >= 12) {
2209 v -= 12;
2210 v |= 0x80;
2211 }
2212 v++;
2213 }
2214 break;
2215 case 6:
2216 v = tecmar_clock_bcd(ct->tm_wday + 1);
2217 break;
2218 case 7:
2219 v = tecmar_clock_bcd(ct->tm_mday);
2220 break;
2221 case 8:
2222 v = tecmar_clock_bcd(ct->tm_mon + 1);
2223 break;
2224 case 9:
2225 v = tecmar_clock_bcd(ct->tm_year % 100);
2226 break;
2227 default:
2228 v = tecmar_clock_regs[tecmar_clock_reg_select];
2229 break;
2230 }
2231 }
2232 return v;
2233 }
2234
ncr80_bget2(struct soft_scsi * ncr,uaecptr addr,int size)2235 static uae_u32 ncr80_bget2(struct soft_scsi *ncr, uaecptr addr, int size)
2236 {
2237 int reg = -1;
2238 uae_u32 v = 0;
2239 int addresstype = -1;
2240 uaecptr origaddr = addr;
2241
2242 addr &= ncr->board_mask;
2243
2244 if (ncr->type == NCR5380_SUPRA) {
2245
2246 if (ncr->subtype == 4) {
2247 if ((addr & 0xc000) == 0xc000) {
2248 v = read_supra_dma(ncr, addr);
2249 } else if (addr & 0x8000) {
2250 addresstype = (addr & 1) ? 0 : 1;
2251 }
2252 } else if (ncr->subtype == 3) {
2253 if ((addr & 0x8000) && !(addr & 1))
2254 addresstype = 0;
2255 } else {
2256 if (ncr->subtype != 1 && (addr & 1)) {
2257 v = 0xff;
2258 } else if (addr & 0x8000) {
2259 addresstype = 1;
2260 } else {
2261 addresstype = 0;
2262 }
2263 }
2264
2265 if (addresstype == 1) {
2266 v = ncr->rom[addr & 0x7fff];
2267 } else if (addresstype == 0) {
2268 reg = suprareg(ncr, addr, false);
2269 if (reg >= 0)
2270 v = ncr5380_bget(ncr, reg);
2271 }
2272
2273 } else if (ncr->type == NONCR_GOLEM) {
2274
2275 int bank = addr & 0x8f81;
2276 struct raw_scsi *rs = &ncr->rscsi;
2277 switch(bank)
2278 {
2279 case 0x8000:
2280 case 0x8001:
2281 case 0x8002:
2282 case 0x8003:
2283 v = raw_scsi_get_data(rs, true);
2284 // message is not retrieved by driver, perhaps hardware does it?
2285 if (rs->bus_phase == SCSI_SIGNAL_PHASE_MESSAGE_IN)
2286 raw_scsi_get_data(rs, true);
2287 break;
2288 case 0x8200:
2289 {
2290 uae_u8 t = raw_scsi_get_signal_phase(rs);
2291 v = 0;
2292 if (!(t & SCSI_IO_BUSY))
2293 v |= 1 << (8 - 8);
2294 if (rs->bus_phase >= 0) {
2295 if (!(rs->bus_phase & SCSI_IO_DIRECTION))
2296 v |= 1 << (13 - 8);
2297 if (!(rs->bus_phase & SCSI_IO_COMMAND))
2298 v |= 1 << (10 - 8);
2299 if (rs->bus_phase != SCSI_SIGNAL_PHASE_STATUS)
2300 v |= 1 << (15 - 8);
2301 }
2302 }
2303 break;
2304 case 0x8201:
2305 {
2306 uae_u8 t = raw_scsi_get_signal_phase(rs);
2307 v = 0;
2308 if (t & SCSI_IO_REQ)
2309 v |= 1 << 6;
2310 }
2311 break;
2312 default:
2313 if ((addr & 0xc000) == 0x0000)
2314 v = ncr->rom[addr];
2315 break;
2316 }
2317
2318 } else if (ncr->type == NCR5380_STARDRIVE) {
2319
2320 struct raw_scsi *rs = &ncr->rscsi;
2321 if (addr < sizeof ncr->acmemory) {
2322 v = ncr->acmemory[addr];
2323 } else {
2324 reg = stardrivereg(ncr, addr);
2325 if (reg >= 0) {
2326 v = ncr5380_bget(ncr, reg);
2327 } else if (addr == 0x104) {
2328 v = 0;
2329 // bit 3: dreq
2330 if (rs->bus_phase >= 0 && (rs->io & SCSI_IO_REQ) && (ncr->regs[2] & 2))
2331 v |= 1 << 3;
2332 }
2333 }
2334
2335 } else if (ncr->type == NCR5380_CLTD) {
2336
2337 struct raw_scsi *rs = &ncr->rscsi;
2338 if (!ncr->configured && addr < sizeof ncr->acmemory) {
2339 v = ncr->acmemory[addr];
2340 } else {
2341 reg = cltdreg(ncr, addr);
2342 if (reg >= 0)
2343 v = ncr5380_bget(ncr, reg);
2344 }
2345
2346 } else if (ncr->type == NCR5380_PTNEXUS) {
2347
2348 struct raw_scsi *rs = &ncr->rscsi;
2349 if (!ncr->configured && addr < sizeof ncr->acmemory) {
2350 v = ncr->acmemory[addr];
2351 } else if (addr & 0x8000) {
2352 v = ncr->rom[addr & 16383];
2353 } else {
2354 reg = ptnexusreg(ncr, addr);
2355 if (reg >= 0) {
2356 v = ncr5380_bget(ncr, reg);
2357 } else if (addr == 0x11) {
2358 // fake dma status
2359 v = 0;
2360 }
2361 }
2362
2363 } else if (ncr->type == NONCR_KOMMOS) {
2364
2365 struct raw_scsi *rs = &ncr->rscsi;
2366 if (addr & 0x8000) {
2367 v = ncr->rom[addr & 0x7fff];
2368 } else if ((origaddr & 0xf00000) != 0xf00000) {
2369 if (!(addr & 8)) {
2370 v = raw_scsi_get_data(rs, true);
2371 } else {
2372 uae_u8 t = raw_scsi_get_signal_phase(rs);
2373 v = 0;
2374 if (t & SCSI_IO_BUSY)
2375 v |= 1 << 1;
2376 if (t & SCSI_IO_REQ)
2377 v |= 1 << 0;
2378 if (t & SCSI_IO_DIRECTION)
2379 v |= 1 << 4;
2380 if (t & SCSI_IO_COMMAND)
2381 v |= 1 << 3;
2382 if (t & SCSI_IO_MESSAGE)
2383 v |= 1 << 2;
2384 }
2385 }
2386
2387 } else if (ncr->type == NONCR_VECTOR) {
2388
2389 struct raw_scsi *rs = &ncr->rscsi;
2390 if (addr < sizeof ncr->acmemory) {
2391 v = ncr->acmemory[addr];
2392 } else if (!(addr & 0x8000)) {
2393 v = ncr->rom[addr];
2394 } else {
2395 if ((addr & 0x201) == 0x200) {
2396 v = (1 << 0);
2397 uae_u8 t = raw_scsi_get_signal_phase(rs);
2398 if (t & SCSI_IO_BUSY)
2399 v &= ~(1 << 0);
2400 if (t & SCSI_IO_DIRECTION)
2401 v |= (1 << 6);
2402 if (t & SCSI_IO_COMMAND)
2403 v |= (1 << 7);
2404 } else if ((addr & 0x201) == 0x201) {
2405 v = 0;
2406 uae_u8 t = raw_scsi_get_signal_phase(rs);
2407 if (t & SCSI_IO_REQ)
2408 v |= 1 << 1;
2409
2410 } else if ((addr & 0x300) == 0x000) {
2411 if (size > 1) {
2412 v = raw_scsi_get_data(rs, true);
2413 vector_scsi_status(rs);
2414 } else {
2415 v = rs->status >= 2 ? 2 : 0;
2416 }
2417 } else if ((addr & 0x300) == 0x300) {
2418 raw_scsi_reset(rs);
2419 }
2420 }
2421
2422 } else if (ncr->type == NCR5380_PROTAR) {
2423
2424 struct raw_scsi *rs = &ncr->rscsi;
2425 if (addr < sizeof ncr->acmemory) {
2426 if (!ncr->configured) {
2427 v = ncr->acmemory[addr];
2428 } else {
2429 reg = protarreg(ncr, addr);
2430 if (reg >= 0) {
2431 v = ncr5380_bget(ncr, reg);
2432 }
2433 }
2434 } else {
2435 v = ncr->rom[addr & 65535];
2436 }
2437
2438 } else if (ncr->type == NCR5380_ADD500) {
2439
2440 struct raw_scsi *rs = &ncr->rscsi;
2441 if (addr & 0x8000) {
2442 uae_u8 t = raw_scsi_get_signal_phase(rs);
2443 if ((addr & 0x8048) == 0x8000) {
2444 if (!(addr & 1)) {
2445 if (t & SCSI_IO_REQ) {
2446 ncr->databuffer[0] = ncr->databuffer[1];
2447 ncr->databuffer[1] = raw_scsi_get_data(rs, true) << 8;
2448 ncr->databuffer[1] |= raw_scsi_get_data(rs, true);
2449 if (ncr->databuffer_empty) {
2450 ncr->databuffer[0] = ncr->databuffer[1];
2451 ncr->databuffer[1] = raw_scsi_get_data(rs, true) << 8;
2452 ncr->databuffer[1] |= raw_scsi_get_data(rs, true);
2453 }
2454 ncr->databuffer_empty = false;
2455 } else {
2456 ncr->databuffer_empty = true;
2457 }
2458 }
2459 v = ncr->databuffer[0] >> 8;
2460 ncr->databuffer[0] <<= 8;
2461 } else {
2462 reg = add500reg(ncr, addr);
2463 if (reg >= 0) {
2464 v = ncr5380_bget(ncr, reg);
2465 } else if ((addr & 0x8049) == 0x8009) {
2466 v = 0;
2467 if (!(t & SCSI_IO_REQ) && ncr->databuffer_empty) {
2468 v |= 1 << 0;
2469 }
2470 }
2471 }
2472 } else {
2473 v = ncr->rom[addr];
2474 }
2475
2476 } else if (ncr->type == NCR5380_ADSCSI) {
2477
2478 struct raw_scsi *rs = &ncr->rscsi;
2479 if (ncr->configured)
2480 reg = adscsireg(ncr, addr, false);
2481 if (reg >= 0) {
2482 v = ncr5380_bget(ncr, reg);
2483 } else {
2484 v = ncr->rom[addr & 65535];
2485 }
2486 if (addr == 0x40) {
2487 uae_u8 t = raw_scsi_get_signal_phase(rs);
2488 v = 0;
2489 // bits 0 to 2: ID (inverted)
2490 v |= (ncr->rc->device_id ^ 7) & 7;
2491 // shorter delay before drive detection (8s vs 18s)
2492 v |= 1 << 5;
2493 if (t & SCSI_IO_REQ) {
2494 v |= 1 << 6;
2495 v |= 1 << 7;
2496 }
2497 }
2498
2499 } else if (ncr->type == NCR5380_KRONOS) {
2500
2501 struct raw_scsi *rs = &ncr->rscsi;
2502 if (addr < sizeof ncr->acmemory)
2503 v = ncr->acmemory[addr];
2504 if (ncr->configured) {
2505 if (addr == 0x40 || addr == 0x41) {
2506 v = 0;
2507 }
2508 }
2509 if (addr & 0x8000) {
2510 v = ncr->rom[addr & 8191];
2511 }
2512
2513 } else if (ncr->type == NCR5380_ROCHARD) {
2514
2515 int reg = (addr & 15) / 2;
2516 if ((addr & 0x300) == 0x300)
2517 v = ncr53400_bget(ncr, reg | 0x100);
2518 else if (addr & 0x200)
2519 v = ncr53400_bget(ncr, reg | 0x80);
2520 else
2521 v = ncr53400_bget(ncr, reg);
2522
2523 } else if (ncr->type == NCR5380_DATAFLYER) {
2524
2525 reg = addr & 0xff;
2526 v = ncr5380_bget(ncr, reg);
2527
2528 } else if (ncr->type == NONCR_TECMAR) {
2529
2530 v = ncr->rom[addr];
2531 if (addr >= 0x2000 && addr < 0x3000) {
2532 if (addr == 0x2040)
2533 v = tecmar_clock_bget(0);
2534 else if (addr == 0x2042)
2535 v = tecmar_clock_bget(1);
2536 } else if (addr >= 0x4000 && addr < 0x5000) {
2537 if (addr == 0x4040)
2538 v = sasi_tecmar_bget(ncr, 1);
2539 else if (addr == 0x4042)
2540 v = sasi_tecmar_bget(ncr, 0);
2541 }
2542
2543 } else if (ncr->type == NCR5380_XEBEC) {
2544
2545 reg = xebec_reg(ncr, addr);
2546 if (reg >= 0 && reg < 8) {
2547 v = ncr5380_bget(ncr, reg);
2548 } else if (reg >= 0x80000) {
2549 v = ncr->databufferptr[reg & (ncr->databuffer_size - 1)];
2550 }
2551
2552 } else if (ncr->type == NONCR_MICROFORGE) {
2553
2554 reg = microforge_reg(ncr, addr, false);
2555 if (reg >= 0)
2556 v = sasi_microforge_bget(ncr, reg);
2557
2558 } else if (ncr->type == OMTI_HDA506) {
2559
2560 reg = hda506_reg(ncr, addr, false);
2561 if (reg >= 0)
2562 v = omti_bget(ncr, reg);
2563
2564 } else if (ncr->type == OMTI_ALF1 || ncr->type == OMTI_ADAPTER) {
2565
2566 reg = alf1_reg(ncr, addr, false);
2567 if (reg >= 0)
2568 v = omti_bget(ncr, reg);
2569
2570 } else if (ncr->type == OMTI_PROMIGOS) {
2571
2572 reg = promigos_reg(ncr, addr, size, false);
2573 if (reg >= 0)
2574 v = omti_bget(ncr, reg);
2575
2576 } else if (ncr->type == OMTI_SYSTEM2000) {
2577
2578 reg = system2000_reg(ncr, addr, size, false);
2579 if (reg >= 0) {
2580 v = omti_bget(ncr, reg);
2581 } else if (addr < 0x4000) {
2582 v = ncr->rom[addr];
2583 } else if (ncr->rscsi.bus_phase >= 0) {
2584 if ((addr & 0xc000) == 0x8000) {
2585 v = ncr->databuffer[addr & 1];
2586 ncr->databuffer[addr & 1] = omti_bget(ncr, 0);
2587 } else if ((addr & 0xc000) == 0xc000) {
2588 v = ncr->databuffer[addr & 1];
2589 }
2590 }
2591
2592 } else if (ncr->type == NCR5380_PHOENIXBOARD) {
2593
2594 reg = phoenixboard_reg(ncr, addr);
2595 if (reg >= 0) {
2596 v = ncr5380_bget(ncr, reg);
2597 } else if (addr < 0x8000) {
2598 v = ncr->rom[addr];
2599 }
2600 }
2601 #if NCR5380_DEBUG > 1
2602 if ((origaddr >= 0xf00000 && size == 1) || (origaddr < 0xf00000))
2603 write_log(_T("GET %08x %02x %d %08x %d\n"), origaddr, v, reg, M68K_GETPC, regs.intmask);
2604 #endif
2605
2606 return v;
2607 }
2608
ncr80_bput2(struct soft_scsi * ncr,uaecptr addr,uae_u32 val,int size)2609 static void ncr80_bput2(struct soft_scsi *ncr, uaecptr addr, uae_u32 val, int size)
2610 {
2611 int reg = -1;
2612 int addresstype = -1;
2613 uaecptr origddr = addr;
2614
2615 addr &= ncr->board_mask;
2616
2617 if (ncr->type == NCR5380_SUPRA) {
2618
2619 if (ncr->subtype == 4) {
2620 if ((addr & 0xc000) == 0xc000) {
2621 write_supra_dma(ncr, addr, val);
2622 } else if (addr & 0x8000) {
2623 addresstype = (addr & 1) ? 0 : 1;
2624 }
2625 } else if (ncr->subtype == 3) {
2626 if ((addr & 0x8000) && !(addr & 1))
2627 addresstype = 0;
2628 } else {
2629 if (ncr->subtype != 1 && (addr & 1))
2630 return;
2631 if (!(addr & 0x8000))
2632 addresstype = 0;
2633 }
2634 if (addresstype == 0) {
2635 reg = suprareg(ncr, addr, true);
2636 if (reg >= 0)
2637 ncr5380_bput(ncr, reg, val);
2638 }
2639
2640 } else if (ncr->type == NONCR_GOLEM) {
2641
2642 int bank = addr & 0x8f81;
2643 struct raw_scsi *rs = &ncr->rscsi;
2644 switch(bank)
2645 {
2646 case 0x8080:
2647 case 0x8081:
2648 case 0x8082:
2649 case 0x8083:
2650 raw_scsi_put_data(rs, val, true);
2651 break;
2652 case 0x8380:
2653 {
2654 raw_scsi_put_data(rs, val, true);
2655 raw_scsi_set_signal_phase(rs, false, true, false);
2656 uae_u8 t = raw_scsi_get_signal_phase(rs);
2657 if (t & SCSI_IO_BUSY)
2658 raw_scsi_set_signal_phase(rs, true, false, false);
2659 }
2660 break;
2661 }
2662
2663 } else if (ncr->type == NCR5380_STARDRIVE) {
2664
2665 reg = stardrivereg(ncr, addr);
2666 if (reg >= 0)
2667 ncr5380_bput(ncr, reg, val);
2668
2669 } else if (ncr->type == NCR5380_CLTD) {
2670
2671 if (ncr->configured) {
2672 reg = cltdreg(ncr, addr);
2673 if (reg >= 0)
2674 ncr5380_bput(ncr, reg, val);
2675 }
2676
2677 } else if (ncr->type == NCR5380_PTNEXUS) {
2678
2679 if (ncr->configured) {
2680 reg = ptnexusreg(ncr, addr);
2681 if (reg >= 0) {
2682 ncr5380_bput(ncr, reg, val);
2683 } else if (addr == 0x11) {
2684 ncr->chip_state = val;
2685 }
2686 }
2687
2688 } else if (ncr->type == NONCR_KOMMOS) {
2689
2690 struct raw_scsi *rs = &ncr->rscsi;
2691 if (!(addr & 0x8000) && (origddr & 0xf00000) != 0xf00000) {
2692 if (!(addr & 8)) {
2693 raw_scsi_put_data(rs, val, true);
2694 } else {
2695 // select?
2696 if (val & 4) {
2697 raw_scsi_set_signal_phase(rs, false, true, false);
2698 uae_u8 t = raw_scsi_get_signal_phase(rs);
2699 if (t & SCSI_IO_BUSY)
2700 raw_scsi_set_signal_phase(rs, true, false, false);
2701 }
2702 }
2703 }
2704
2705 } else if (ncr->type == NONCR_VECTOR) {
2706
2707 struct raw_scsi *rs = &ncr->rscsi;
2708 if (addr & 0x8000) {
2709 if ((addr & 0x300) == 0x300) {
2710 raw_scsi_put_data(rs, val, false);
2711 raw_scsi_set_signal_phase(rs, false, true, false);
2712 uae_u8 t = raw_scsi_get_signal_phase(rs);
2713 if (t & SCSI_IO_BUSY)
2714 raw_scsi_set_signal_phase(rs, true, false, false);
2715 } else if ((addr & 0x300) == 0x000) {
2716 raw_scsi_put_data(rs, val, true);
2717 vector_scsi_status(rs);
2718 }
2719
2720 }
2721
2722 } else if (ncr->type == NCR5380_PROTAR) {
2723
2724 reg = protarreg(ncr, addr);
2725 if (reg >= 0)
2726 ncr5380_bput(ncr, reg, val);
2727
2728 } else if (ncr->type == NCR5380_ADD500) {
2729
2730 if ((addr & 0x8048) == 0x8008) {
2731 struct raw_scsi *rs = &ncr->rscsi;
2732 ncr->databuffer_empty = true;
2733 } else {
2734 reg = add500reg(ncr, addr);
2735 if (reg >= 0) {
2736 ncr5380_bput(ncr, reg, val);
2737 }
2738 }
2739
2740 } else if (ncr->type == NCR5380_ADSCSI) {
2741
2742 if (ncr->configured)
2743 reg = adscsireg(ncr, addr, true);
2744 if (reg >= 0) {
2745 ncr5380_bput(ncr, reg, val);
2746 }
2747
2748 } else if (ncr->type == NCR5380_KRONOS) {
2749
2750 if (addr == 0x60 || addr == 0x61) {
2751 ;
2752 }
2753
2754 } else if (ncr->type == NCR5380_ROCHARD) {
2755
2756 int reg = (addr & 15) / 2;
2757 if ((addr & 0x300) == 0x300)
2758 ncr53400_bput(ncr, reg | 0x100, val);
2759 else if (addr & 0x200)
2760 ncr53400_bput(ncr, reg | 0x80, val);
2761 else
2762 ncr53400_bput(ncr, reg, val);
2763
2764 } else if (ncr->type == NCR5380_DATAFLYER) {
2765
2766 reg = addr & 0xff;
2767 ncr5380_bput(ncr, reg, val);
2768
2769 } else if (ncr->type == NONCR_TECMAR) {
2770
2771 if (addr == 0x22) {
2772 // box
2773 ncr->baseaddress = 0xe80000 + ((val & 0x7f) * 4096);
2774 map_banks_z2(ncr->bank, ncr->baseaddress >> 16, 1);
2775 expamem_next(ncr->bank, NULL);
2776 } else if (addr == 0x1020) {
2777 // memory board control/status
2778 ncr->rom[addr] = val & (0x80 | 0x40 | 0x02);
2779 } else if (addr == 0x1024) {
2780 // memory board memory address reg
2781 if (currprefs.fastmem2_size)
2782 map_banks_z2(&fastmem2_bank, val, currprefs.fastmem2_size >> 16);
2783 }
2784 else if (addr >= 0x2000 && addr < 0x3000) {
2785 // clock
2786 if (addr == 0x2040)
2787 tecmar_clock_bput(0, val);
2788 else if (addr == 0x2042)
2789 tecmar_clock_bput(1, val);
2790 } else if (addr >= 0x4000 && addr < 0x5000) {
2791 // sasi
2792 if (addr == 0x4040)
2793 sasi_tecmar_bput(ncr, 1, val);
2794 else if (addr == 0x4042)
2795 sasi_tecmar_bput(ncr, 0, val);
2796 }
2797
2798 } else if (ncr->type == NCR5380_XEBEC) {
2799
2800 reg = xebec_reg(ncr, addr);
2801 if (reg >= 0 && reg < 8) {
2802 ncr5380_bput(ncr, reg, val);
2803 } else if (reg >= 0x80000) {
2804 ncr->databufferptr[reg & (ncr->databuffer_size - 1)] = val;
2805 }
2806
2807 } else if (ncr->type == NONCR_MICROFORGE) {
2808
2809 reg = microforge_reg(ncr, addr, true);
2810 if (reg >= 0)
2811 sasi_microforge_bput(ncr, reg, val);
2812
2813 } else if (ncr->type == OMTI_HDA506) {
2814
2815 reg = hda506_reg(ncr, addr, true);
2816 if (reg >= 0)
2817 omti_bput(ncr, reg, val);
2818
2819 } else if (ncr->type == OMTI_ALF1 || ncr->type == OMTI_ADAPTER) {
2820
2821 reg = alf1_reg(ncr, addr, true);
2822 if (reg >= 0)
2823 omti_bput(ncr, reg, val);
2824
2825 } else if (ncr->type == OMTI_PROMIGOS) {
2826
2827 reg = promigos_reg(ncr, addr, size, true);
2828 if (reg >= 0)
2829 omti_bput(ncr, reg, val);
2830
2831 } else if (ncr->type == OMTI_SYSTEM2000) {
2832
2833 reg = system2000_reg(ncr, addr, size, true);
2834 if (reg >= 0) {
2835 omti_bput(ncr, reg, val);
2836 } else if (ncr->rscsi.bus_phase >= 0) {
2837 if ((addr & 0x8000) == 0x8000) {
2838 omti_bput(ncr, 0, val);
2839 }
2840 }
2841
2842 } else if (ncr->type == NCR5380_PHOENIXBOARD) {
2843
2844 reg = phoenixboard_reg(ncr, addr);
2845 if (reg >= 0) {
2846 ncr5380_bput(ncr, reg, val);
2847 }
2848
2849 }
2850
2851 #if NCR5380_DEBUG > 1
2852 write_log(_T("PUT %08x %02x %d %08x %d\n"), origddr, val, reg, M68K_GETPC, regs.intmask);
2853 #endif
2854 }
2855
2856 // x86 bridge hd
x86_xt_hd_bput(int portnum,uae_u8 v)2857 void x86_xt_hd_bput(int portnum, uae_u8 v)
2858 {
2859 struct soft_scsi *scsi = x86_hd_data;
2860 write_log(_T("X86 HD PUT %04x = %02x\n"), portnum, v);
2861 if (!scsi)
2862 return;
2863 if (portnum < 0) {
2864 struct raw_scsi *rs = &scsi->rscsi;
2865 raw_scsi_busfree(rs);
2866 scsi->chip_state = 0;
2867 return;
2868 }
2869 omti_bput(scsi, v & 3, v);
2870 }
x86_xt_hd_bget(int portnum)2871 uae_u8 x86_xt_hd_bget(int portnum)
2872 {
2873 uae_u8 v = 0xff;
2874 struct soft_scsi *scsi = x86_hd_data;
2875 write_log(_T("X86 HD GET %04x\n"), portnum);
2876 if (!scsi)
2877 return v;
2878 v = omti_bget(scsi, v & 3);
2879 return v;
2880 }
2881
2882 // mainhattan paradox scsi
parallel_port_scsi_read(int reg,uae_u8 data,uae_u8 dir)2883 uae_u8 parallel_port_scsi_read(int reg, uae_u8 data, uae_u8 dir)
2884 {
2885 struct soft_scsi *scsi = parallel_port_scsi_data;
2886 if (!scsi)
2887 return data;
2888 struct raw_scsi *rs = &scsi->rscsi;
2889 uae_u8 t = raw_scsi_get_signal_phase(rs);
2890 if (reg == 0) {
2891 data = raw_scsi_get_data_2(rs, true, false);
2892 data ^= 0xff;
2893 } else if (reg == 1) {
2894 data &= ~3;
2895 if (rs->bus_phase >= 0 && !(rs->bus_phase & SCSI_IO_COMMAND))
2896 data |= 2; // POUT
2897 data |= 1;
2898 if (rs->bus_phase == SCSI_SIGNAL_PHASE_SELECT_2 || rs->bus_phase >= 0)
2899 data &= ~1; // BUSY
2900 }
2901 t = raw_scsi_get_signal_phase(rs);
2902 if ((t & SCSI_IO_REQ) && (scsi->chip_state & 4))
2903 cia_parallelack();
2904 return data;
2905 }
parallel_port_scsi_write(int reg,uae_u8 v,uae_u8 dir)2906 void parallel_port_scsi_write(int reg, uae_u8 v, uae_u8 dir)
2907 {
2908 struct soft_scsi *scsi = parallel_port_scsi_data;
2909 if (!scsi)
2910 return;
2911 struct raw_scsi *rs = &scsi->rscsi;
2912 if (reg == 0) {
2913 v ^= 0xff;
2914 raw_scsi_put_data(rs, v, true);
2915 } else if (reg == 1) {
2916 // SEL
2917 if (!(v & 4) && (scsi->chip_state & 4)) {
2918 raw_scsi_set_signal_phase(rs, false, true, false);
2919 } else if ((v & 4) && !(scsi->chip_state & 4)) {
2920 if (rs->bus_phase == SCSI_SIGNAL_PHASE_SELECT_2) {
2921 raw_scsi_set_signal_phase(rs, false, false, false);
2922 }
2923 }
2924 scsi->chip_state = v;
2925 }
2926 uae_u8 t = raw_scsi_get_signal_phase(rs);
2927 if ((t & SCSI_IO_REQ) && (scsi->chip_state & 4))
2928 cia_parallelack();
2929 }
2930
ncr80_lget(struct soft_scsi * ncr,uaecptr addr)2931 static uae_u32 REGPARAM2 ncr80_lget(struct soft_scsi *ncr, uaecptr addr)
2932 {
2933 uae_u32 v;
2934 v = ncr80_bget2(ncr, addr + 0, 4) << 24;
2935 v |= ncr80_bget2(ncr, addr + 1, 4) << 16;
2936 v |= ncr80_bget2(ncr, addr + 2, 4) << 8;
2937 v |= ncr80_bget2(ncr, addr + 3, 4) << 0;
2938 return v;
2939 }
2940
ncr80_wget(struct soft_scsi * ncr,uaecptr addr)2941 static uae_u32 REGPARAM2 ncr80_wget(struct soft_scsi *ncr, uaecptr addr)
2942 {
2943 uae_u32 v;
2944 v = ncr80_bget2(ncr, addr, 2) << 8;
2945 v |= ncr80_bget2(ncr, addr + 1, 2);
2946 return v;
2947 }
2948
ncr80_bget(struct soft_scsi * ncr,uaecptr addr)2949 static uae_u32 REGPARAM2 ncr80_bget(struct soft_scsi *ncr, uaecptr addr)
2950 {
2951 uae_u32 v;
2952 addr &= ncr->board_mask;
2953 if (!ncr->configured) {
2954 addr &= 65535;
2955 if (addr >= sizeof ncr->acmemory)
2956 return 0;
2957 return ncr->acmemory[addr];
2958 }
2959 v = ncr80_bget2(ncr, addr, 1);
2960 return v;
2961 }
2962
ncr80_lput(struct soft_scsi * ncr,uaecptr addr,uae_u32 l)2963 static void REGPARAM2 ncr80_lput(struct soft_scsi *ncr, uaecptr addr, uae_u32 l)
2964 {
2965 ncr80_bput2(ncr, addr + 0, l >> 24, 4);
2966 ncr80_bput2(ncr, addr + 1, l >> 16, 4);
2967 ncr80_bput2(ncr, addr + 2, l >> 8, 4);
2968 ncr80_bput2(ncr, addr + 3, l >> 0, 4);
2969 }
2970
ncr80_wput(struct soft_scsi * ncr,uaecptr addr,uae_u32 w)2971 static void REGPARAM2 ncr80_wput(struct soft_scsi *ncr, uaecptr addr, uae_u32 w)
2972 {
2973 w &= 0xffff;
2974 if (!ncr->configured) {
2975 return;
2976 }
2977 ncr80_bput2(ncr, addr, w >> 8, 2);
2978 ncr80_bput2(ncr, addr + 1, w & 0xff, 2);
2979 }
2980
ncr80_bput(struct soft_scsi * ncr,uaecptr addr,uae_u32 b)2981 static void REGPARAM2 ncr80_bput(struct soft_scsi *ncr, uaecptr addr, uae_u32 b)
2982 {
2983 b &= 0xff;
2984 addr &= ncr->board_mask;
2985 if (!ncr->configured) {
2986 addr &= 65535;
2987 switch (addr)
2988 {
2989 case 0x48:
2990 map_banks_z2(ncr->bank, expamem_z2_pointer >> 16, ncr->board_size >> 16);
2991 ncr->baseaddress = expamem_z2_pointer;
2992 ncr->configured = 1;
2993 expamem_next (ncr->bank, NULL);
2994 break;
2995 case 0x4c:
2996 ncr->configured = 1;
2997 expamem_shutup(ncr->bank);
2998 break;
2999 }
3000 return;
3001 }
3002 ncr80_bput2(ncr, addr, b, 1);
3003 }
3004
soft_generic_bput(uaecptr addr,uae_u32 b)3005 static void REGPARAM2 soft_generic_bput (uaecptr addr, uae_u32 b)
3006 {
3007 struct soft_scsi *ncr = getscsiboard(addr);
3008 if (ncr)
3009 ncr80_bput(ncr, addr, b);
3010 }
3011
soft_generic_wput(uaecptr addr,uae_u32 b)3012 static void REGPARAM2 soft_generic_wput (uaecptr addr, uae_u32 b)
3013 {
3014 struct soft_scsi *ncr = getscsiboard(addr);
3015 if (ncr)
3016 ncr80_wput(ncr, addr, b);
3017 }
soft_generic_lput(uaecptr addr,uae_u32 b)3018 static void REGPARAM2 soft_generic_lput (uaecptr addr, uae_u32 b)
3019 {
3020 struct soft_scsi *ncr = getscsiboard(addr);
3021 if (ncr)
3022 ncr80_lput(ncr, addr, b);
3023 }
soft_generic_bget(uaecptr addr)3024 static uae_u32 REGPARAM2 soft_generic_bget (uaecptr addr)
3025 {
3026 struct soft_scsi *ncr = getscsiboard(addr);
3027 if (ncr)
3028 return ncr80_bget(ncr, addr);
3029 return 0;
3030 }
soft_generic_wget(uaecptr addr)3031 static uae_u32 REGPARAM2 soft_generic_wget (uaecptr addr)
3032 {
3033 struct soft_scsi *ncr = getscsiboard(addr);
3034 if (ncr)
3035 return ncr80_wget(ncr, addr);
3036 return 0;
3037 }
soft_generic_lget(uaecptr addr)3038 static uae_u32 REGPARAM2 soft_generic_lget (uaecptr addr)
3039 {
3040 struct soft_scsi *ncr = getscsiboard(addr);
3041 if (ncr)
3042 return ncr80_lget(ncr, addr);
3043 return 0;
3044 }
3045
soft_check(uaecptr addr,uae_u32 size)3046 static int REGPARAM2 soft_check(uaecptr addr, uae_u32 size)
3047 {
3048 struct soft_scsi *ncr = getscsiboard(addr);
3049 if (!ncr)
3050 return 0;
3051 if (!ncr->rom)
3052 return 0;
3053 return 1;
3054 }
soft_xlate(uaecptr addr)3055 static uae_u8 *REGPARAM2 soft_xlate(uaecptr addr)
3056 {
3057 struct soft_scsi *ncr = getscsiboard(addr);
3058 if (!ncr)
3059 return 0;
3060 return ncr->rom + (addr & (ncr->rom_size - 1));
3061 }
3062
3063 addrbank soft_bank_generic = {
3064 soft_generic_lget, soft_generic_wget, soft_generic_bget,
3065 soft_generic_lput, soft_generic_wput, soft_generic_bput,
3066 soft_xlate, soft_check, NULL, NULL, _T("LOWLEVEL/5380 SCSI"),
3067 soft_generic_lget, soft_generic_wget,
3068 ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
3069 };
3070
soft_scsi_put(uaecptr addr,int size,uae_u32 v)3071 void soft_scsi_put(uaecptr addr, int size, uae_u32 v)
3072 {
3073 if (size == 4)
3074 soft_generic_lput(addr, v);
3075 else if (size == 2)
3076 soft_generic_wput(addr, v);
3077 else
3078 soft_generic_bput(addr, v);
3079 }
soft_scsi_get(uaecptr addr,int size)3080 uae_u32 soft_scsi_get(uaecptr addr, int size)
3081 {
3082 uae_u32 v;
3083 if (size == 4)
3084 v = soft_generic_lget(addr);
3085 else if (size == 2)
3086 v = soft_generic_wget(addr);
3087 else
3088 v = soft_generic_bget(addr);
3089 return v;
3090 }
3091
soft_scsi_free(void)3092 void soft_scsi_free(void)
3093 {
3094 parallel_port_scsi = false;
3095 parallel_port_scsi_data = NULL;
3096 x86_hd_data = NULL;
3097 for (int i = 0; soft_scsi_devices[i]; i++) {
3098 soft_scsi_free_unit(soft_scsi_devices[i]);
3099 soft_scsi_devices[i] = NULL;
3100 }
3101 }
3102
soft_scsi_reset(void)3103 void soft_scsi_reset(void)
3104 {
3105 for (int i = 0; soft_scsi_devices[i]; i++) {
3106 raw_scsi_reset(&soft_scsi_devices[i]->rscsi);
3107 }
3108 }
3109
3110 /*
3111 $8380 select unit (unit mask)
3112
3113 $8200
3114 6: REQ (1=active)
3115 8: BSY (0=active)
3116 10: C/D (1=data)
3117 13: I/O (1=to target)
3118 15: If not status?
3119
3120 $8080 write data
3121 $8000 read data
3122
3123 */
3124
supra_init(struct romconfig * rc)3125 addrbank *supra_init(struct romconfig *rc)
3126 {
3127 struct soft_scsi *scsi = getscsi(rc);
3128
3129 if (!scsi)
3130 return &expamem_null;
3131
3132 scsi->intena = true;
3133
3134 const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_SUPRA);
3135 struct zfile *z = NULL;
3136 scsi->subtype = rc->subtype;
3137 if (!rc->autoboot_disabled && scsi->subtype != 3) {
3138 for (int i = 0; i < 16; i++) {
3139 uae_u8 b = ert->subtypes[rc->subtype].autoconfig[i];
3140 ew(scsi, i * 4, b);
3141 }
3142 load_rom_rc(rc, ROMTYPE_SUPRA, 16384, 0, scsi->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
3143 }
3144 return scsi->bank;
3145 }
3146
supra_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3147 void supra_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3148 {
3149 generic_soft_scsi_add(ch, ci, rc, NCR5380_SUPRA, 65536, 2 * 16384, ROMTYPE_SUPRA);
3150 }
3151
golem_init(struct romconfig * rc)3152 addrbank *golem_init(struct romconfig *rc)
3153 {
3154 struct soft_scsi *scsi = getscsi(rc);
3155
3156 if (!scsi)
3157 return &expamem_null;
3158
3159 scsi->intena = true;
3160
3161 load_rom_rc(rc, ROMTYPE_GOLEM, 8192, rc->autoboot_disabled ? 8192 : 0, scsi->rom, 8192, 0);
3162 memcpy(scsi->acmemory, scsi->rom, sizeof scsi->acmemory);
3163
3164 return scsi->bank;
3165 }
3166
golem_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3167 void golem_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3168 {
3169 generic_soft_scsi_add(ch, ci, rc, NONCR_GOLEM, 65536, 8192, ROMTYPE_GOLEM);
3170 }
3171
stardrive_init(struct romconfig * rc)3172 addrbank *stardrive_init(struct romconfig *rc)
3173 {
3174 struct soft_scsi *scsi = getscsi(rc);
3175
3176 if (!scsi)
3177 return &expamem_null;
3178
3179 const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_STARDRIVE);
3180 for (int i = 0; i < 16; i++) {
3181 uae_u8 b = ert->autoconfig[i];
3182 ew(scsi, i * 4, b);
3183 }
3184 return scsi->bank;
3185 }
3186
stardrive_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3187 void stardrive_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3188 {
3189 generic_soft_scsi_add(ch, ci, rc, NCR5380_STARDRIVE, 65536, 0, ROMTYPE_STARDRIVE);
3190 }
3191
kommos_init(struct romconfig * rc)3192 addrbank *kommos_init(struct romconfig *rc)
3193 {
3194 struct soft_scsi *scsi = getscsi(rc);
3195
3196 if (!scsi)
3197 return NULL;
3198
3199 scsi->configured = 1;
3200
3201 load_rom_rc(rc, ROMTYPE_KOMMOS, 32768, 0, scsi->rom, 32768, 0);
3202
3203 map_banks(scsi->bank, 0xf10000 >> 16, 1, 0);
3204 map_banks(scsi->bank, 0xeb0000 >> 16, 1, 0);
3205 scsi->baseaddress = 0xeb0000;
3206 scsi->baseaddress2 = 0xf10000;
3207
3208 return NULL;
3209 }
3210
kommos_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3211 void kommos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3212 {
3213 generic_soft_scsi_add(ch, ci, rc, NONCR_KOMMOS, 65536, 32768, ROMTYPE_KOMMOS);
3214 }
3215
vector_init(struct romconfig * rc)3216 addrbank *vector_init(struct romconfig *rc)
3217 {
3218 struct soft_scsi *scsi = getscsi(rc);
3219 int roms[2];
3220
3221 if (!scsi)
3222 return &expamem_null;
3223
3224 roms[0] = 128;
3225 roms[1] = -1;
3226
3227 scsi->intena = true;
3228
3229 if (!rc->autoboot_disabled) {
3230 load_rom_rc(rc, ROMTYPE_VECTOR, 32768, 0, scsi->rom, 32768, 0);
3231 memcpy(scsi->acmemory, scsi->rom, sizeof scsi->acmemory);
3232 }
3233 return scsi->bank;
3234 }
3235
vector_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3236 void vector_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3237 {
3238 generic_soft_scsi_add(ch, ci, rc, NONCR_VECTOR, 65536, 32768, ROMTYPE_VECTOR);
3239 }
3240
3241
protar_init(struct romconfig * rc)3242 addrbank *protar_init(struct romconfig *rc)
3243 {
3244 struct soft_scsi *scsi = getscsi(rc);
3245
3246 if (!scsi)
3247 return &expamem_null;
3248
3249 load_rom_rc(rc, ROMTYPE_PROTAR, 32768, 0, scsi->rom, 32768, LOADROM_EVENONLY_ODDONE);
3250 memcpy(scsi->acmemory, scsi->rom + 0x200 * 2, sizeof scsi->acmemory);
3251 return scsi->bank;
3252 }
3253
protar_add_ide_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3254 void protar_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3255 {
3256 generic_soft_scsi_add(ch, ci, rc, NCR5380_PROTAR, 65536, 65536, ROMTYPE_PROTAR);
3257 }
3258
add500_init(struct romconfig * rc)3259 addrbank *add500_init(struct romconfig *rc)
3260 {
3261 struct soft_scsi *scsi = getscsi(rc);
3262
3263 if (!scsi)
3264 return &expamem_null;
3265
3266 load_rom_rc(rc, ROMTYPE_ADD500, 16384, 0, scsi->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
3267 memcpy(scsi->acmemory, scsi->rom, sizeof scsi->acmemory);
3268 return scsi->bank;
3269 }
3270
add500_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3271 void add500_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3272 {
3273 generic_soft_scsi_add(ch, ci, rc, NCR5380_ADD500, 65536, 32768, ROMTYPE_ADD500);
3274 }
3275
kronos_init(struct romconfig * rc)3276 addrbank *kronos_init(struct romconfig *rc)
3277 {
3278 struct soft_scsi *scsi = getscsi(rc);
3279
3280 if (!scsi)
3281 return &expamem_null;
3282
3283 scsi->databuffer_size = 1024;
3284 scsi->databufferptr = xcalloc(uae_u8, scsi->databuffer_size);
3285
3286 load_rom_rc(rc, ROMTYPE_KRONOS, 4096, 0, scsi->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
3287 return scsi->bank;
3288 }
3289
kronos_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3290 void kronos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3291 {
3292 generic_soft_scsi_add(ch, ci, rc, NCR5380_KRONOS, 65536, 32768, ROMTYPE_KRONOS);
3293 }
3294
adscsi_init(struct romconfig * rc)3295 addrbank *adscsi_init(struct romconfig *rc)
3296 {
3297 struct soft_scsi *scsi = getscsi(rc);
3298
3299 if (!scsi)
3300 return &expamem_null;
3301
3302 load_rom_rc(rc, ROMTYPE_ADSCSI, 32768, 0, scsi->rom, 65536, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
3303 memcpy(scsi->acmemory, scsi->rom, sizeof scsi->acmemory);
3304 return scsi->bank;
3305 }
3306
adscsi_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3307 void adscsi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3308 {
3309 generic_soft_scsi_add(ch, ci, rc, NCR5380_ADSCSI, 65536, 65536, ROMTYPE_ADSCSI);
3310 }
3311
rochard_scsi_init(struct romconfig * rc,uaecptr baseaddress)3312 bool rochard_scsi_init(struct romconfig *rc, uaecptr baseaddress)
3313 {
3314 struct soft_scsi *scsi = getscsi(rc);
3315 scsi->configured = 1;
3316 scsi->dma_controller = true;
3317 scsi->baseaddress = baseaddress;
3318 return scsi != NULL;
3319 }
rochard_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3320 void rochard_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3321 {
3322 generic_soft_scsi_add(ch, ci, rc, NCR5380_ROCHARD, 65536, -1, ROMTYPE_ROCHARD);
3323 }
3324
rochard_scsi_get(uaecptr addr)3325 uae_u8 rochard_scsi_get(uaecptr addr)
3326 {
3327 return soft_generic_bget(addr);
3328 }
3329
rochard_scsi_put(uaecptr addr,uae_u8 v)3330 void rochard_scsi_put(uaecptr addr, uae_u8 v)
3331 {
3332 soft_generic_bput(addr, v);
3333 }
3334
cltda1000scsi_init(struct romconfig * rc)3335 addrbank *cltda1000scsi_init(struct romconfig *rc) {
3336 struct soft_scsi *scsi = getscsi(rc);
3337
3338 if (!scsi)
3339 return &expamem_null;
3340
3341 scsi->intena = true;
3342 scsi->delayed_irq = true;
3343
3344 const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_CLTDSCSI);
3345 for (int i = 0; i < 16; i++) {
3346 uae_u8 b = ert->autoconfig[i];
3347 ew(scsi, i * 4, b);
3348 }
3349 return scsi->bank;
3350 }
3351
cltda1000scsi_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3352 void cltda1000scsi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3353 {
3354 generic_soft_scsi_add(ch, ci, rc, NCR5380_CLTD, 65536, 0, ROMTYPE_CLTDSCSI);
3355 }
3356
ptnexus_init(struct romconfig * rc)3357 addrbank *ptnexus_init(struct romconfig *rc)
3358 {
3359 struct soft_scsi *scsi = getscsi(rc);
3360
3361 if (!scsi)
3362 return &expamem_null;
3363
3364 scsi->intena = true;
3365 scsi->delayed_irq = true;
3366
3367 const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_PTNEXUS);
3368 for (int i = 0; i < 16; i++) {
3369 uae_u8 b = ert->autoconfig[i];
3370 ew(scsi, i * 4, b);
3371 }
3372
3373 load_rom_rc(rc, ROMTYPE_PTNEXUS, 8192, 0, scsi->rom, 65536, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
3374 return scsi->bank;
3375 }
3376
ptnexus_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3377 void ptnexus_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3378 {
3379 generic_soft_scsi_add(ch, ci, rc, NCR5380_PTNEXUS, 65536, 65536, ROMTYPE_PTNEXUS);
3380 }
3381
dataflyer_init(struct romconfig * rc)3382 addrbank *dataflyer_init(struct romconfig *rc)
3383 {
3384 struct soft_scsi *scsi = getscsi(rc);
3385
3386 if (!scsi)
3387 return &expamem_null;
3388
3389 scsi->baseaddress = (currprefs.cs_ide == IDE_A4000) ? 0xdd2000 : 0xda0000;
3390 scsi->configured = true;
3391
3392 gayle_dataflyer_enable(true);
3393
3394 return NULL;
3395 }
3396
dataflyer_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3397 void dataflyer_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3398 {
3399 generic_soft_scsi_add(ch, ci, rc, NCR5380_DATAFLYER, 4096, 0, ROMTYPE_DATAFLYER);
3400 }
3401
expansion_add_protoautoconfig_data(uae_u8 * p,uae_u16 manufacturer_id,uae_u8 product_id)3402 static void expansion_add_protoautoconfig_data(uae_u8 *p, uae_u16 manufacturer_id, uae_u8 product_id)
3403 {
3404 memset(p, 0, 4096);
3405 p[0x02] = product_id;
3406 p[0x08] = manufacturer_id >> 8;
3407 p[0x0a] = (uae_u8)manufacturer_id;
3408 }
3409
expansion_add_protoautoconfig_box(uae_u8 * p,int box_size,uae_u16 manufacturer_id,uae_u8 product_id)3410 static void expansion_add_protoautoconfig_box(uae_u8 *p, int box_size, uae_u16 manufacturer_id, uae_u8 product_id)
3411 {
3412 expansion_add_protoautoconfig_data(p, manufacturer_id, product_id);
3413 // "box without init/diagnostics code"
3414 p[0] = 0x40 | (box_size << 3);
3415 }
expansion_add_protoautoconfig_board(uae_u8 * p,int board,uae_u16 manufacturer_id,uae_u8 product_id,int memorysize)3416 static void expansion_add_protoautoconfig_board(uae_u8 *p, int board, uae_u16 manufacturer_id, uae_u8 product_id, int memorysize)
3417 {
3418 p += (board + 1) * 4096;
3419 expansion_add_protoautoconfig_data(p, manufacturer_id, product_id);
3420 // "board without init/diagnostic code"
3421 p[0] = 0x08;
3422 if (memorysize) {
3423 int v = 0;
3424 switch (memorysize)
3425 {
3426 case 64 * 1024:
3427 v = 1;
3428 break;
3429 case 128 * 1024:
3430 v = 2;
3431 break;
3432 case 256 * 1024:
3433 v = 3;
3434 break;
3435 case 512 * 1024:
3436 v = 4;
3437 break;
3438 case 1024 * 1024:
3439 v = 5;
3440 break;
3441 case 2048 * 1024:
3442 v = 6;
3443 break;
3444 case 4096 * 1024:
3445 default:
3446 v = 7;
3447 break;
3448 }
3449 p[0] |= v;
3450 }
3451 }
3452
tecmar_init(struct romconfig * rc)3453 addrbank *tecmar_init(struct romconfig *rc)
3454 {
3455 struct soft_scsi *scsi = getscsi(rc);
3456 int index = 0;
3457
3458 if (!scsi)
3459 return &expamem_null;
3460
3461 const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_PTNEXUS);
3462 scsi->rom = xcalloc(uae_u8, 65536);
3463 expansion_add_protoautoconfig_box(scsi->rom, 3, 1001, 0);
3464 // memory
3465 expansion_add_protoautoconfig_board(scsi->rom, index++, 1001, 1, currprefs.fastmem2_size);
3466 // clock
3467 expansion_add_protoautoconfig_board(scsi->rom, index++, 1001, 2, 0);
3468 // serial
3469 expansion_add_protoautoconfig_board(scsi->rom, index++, 1001, 3, 0);
3470 // parallel
3471 expansion_add_protoautoconfig_board(scsi->rom, index++, 1001, 4, 0);
3472 // sasi
3473 expansion_add_protoautoconfig_board(scsi->rom, index++, 1001, 4, 0);
3474 memset(tecmar_clock_regs, 0, sizeof tecmar_clock_regs);
3475 tecmar_clock_regs[11] = 0x04 | 0x02 | 0x01;
3476 scsi->configured = true;
3477 scsi->baseaddress = 0xe80000;
3478 return scsi->bank;
3479 }
3480
tecmar_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3481 void tecmar_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3482 {
3483 generic_soft_scsi_add(ch, ci, rc, NONCR_TECMAR, 65536, 65536, ROMTYPE_TECMAR);
3484 }
3485
microforge_init(struct romconfig * rc)3486 addrbank *microforge_init(struct romconfig *rc)
3487 {
3488 struct soft_scsi *scsi = getscsi(rc);
3489
3490 if (!scsi)
3491 return NULL;
3492
3493 scsi->configured = 1;
3494
3495 map_banks(scsi->bank, 0xef0000 >> 16, 0x10000 >> 16, 0);
3496 scsi->baseaddress = 0xef0000;
3497 return NULL;
3498 }
3499
microforge_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3500 void microforge_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3501 {
3502 generic_soft_scsi_add(ch, ci, rc, NONCR_MICROFORGE, 65536, 0, ROMTYPE_MICROFORGE);
3503 }
3504
xebec_init(struct romconfig * rc)3505 addrbank *xebec_init(struct romconfig *rc)
3506 {
3507 struct soft_scsi *scsi = getscsi(rc);
3508
3509 if (!scsi)
3510 return NULL;
3511
3512 scsi->configured = 1;
3513
3514 map_banks(scsi->bank, 0x600000 >> 16, (0x800000 - 0x600000) >> 16, 0);
3515 scsi->board_mask = 0x1fffff;
3516 scsi->baseaddress = 0x600000;
3517 scsi->level6 = true;
3518 scsi->intena = true;
3519 scsi->dma_controller = true;
3520 scsi->databuffer_size = 32768;
3521 scsi->databufferptr = xcalloc(uae_u8, scsi->databuffer_size);
3522 return NULL;
3523 }
3524
xebec_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3525 void xebec_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3526 {
3527 generic_soft_scsi_add(ch, ci, rc, NCR5380_XEBEC, 65536, 0, ROMTYPE_XEBEC);
3528 }
3529
paradox_init(struct romconfig * rc)3530 addrbank *paradox_init(struct romconfig *rc)
3531 {
3532 struct soft_scsi *scsi = getscsi(rc);
3533
3534 if (!scsi)
3535 return NULL;
3536
3537 scsi->configured = 1;
3538 parallel_port_scsi = true;
3539 parallel_port_scsi_data = scsi;
3540
3541 return NULL;
3542 }
3543
paradox_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3544 void paradox_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3545 {
3546 generic_soft_scsi_add(ch, ci, rc, NONCR_PARADOX, 0, 0, ROMTYPE_PARADOX);
3547 }
3548
hda506_init(struct romconfig * rc)3549 addrbank *hda506_init(struct romconfig *rc)
3550 {
3551 struct soft_scsi *scsi = getscsi(rc);
3552
3553 if (!scsi)
3554 return NULL;
3555
3556 const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_HDA506);
3557 for (int i = 0; i < 16; i++) {
3558 uae_u8 b = ert->autoconfig[i];
3559 ew(scsi, i * 4, b);
3560 }
3561 scsi->level6 = true;
3562 scsi->intena = true;
3563 return scsi->bank;
3564 }
3565
hda506_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3566 void hda506_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3567 {
3568 generic_soft_scsi_add(ch, ci, rc, OMTI_HDA506, 0, 0, ROMTYPE_HDA506);
3569 }
3570
alf1_init(struct romconfig * rc)3571 addrbank *alf1_init(struct romconfig *rc)
3572 {
3573 struct soft_scsi *scsi = getscsi(rc);
3574
3575 if (!scsi)
3576 return NULL;
3577 map_banks(scsi->bank, 0xef0000 >> 16, 0x10000 >> 16, 0);
3578 scsi->board_mask = 0xffff;
3579 scsi->baseaddress = 0xef0000;
3580 scsi->configured = 1;
3581
3582 return scsi->bank;
3583 }
3584
alf1_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3585 void alf1_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3586 {
3587 generic_soft_scsi_add(ch, ci, rc, OMTI_ALF1, 65536, 0, ROMTYPE_ALF1);
3588 }
3589
promigos_init(struct romconfig * rc)3590 addrbank *promigos_init(struct romconfig *rc)
3591 {
3592 struct soft_scsi *scsi = getscsi(rc);
3593
3594 if (!scsi)
3595 return NULL;
3596 map_banks(scsi->bank, 0xf40000 >> 16, 0x10000 >> 16, 0);
3597 scsi->board_mask = 0xffff;
3598 scsi->baseaddress = 0xf40000;
3599 scsi->configured = 1;
3600 scsi->intena = true;
3601
3602 return scsi->bank;
3603 }
3604
promigos_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3605 void promigos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3606 {
3607 generic_soft_scsi_add(ch, ci, rc, OMTI_PROMIGOS, 65536, 0, ROMTYPE_PROMIGOS);
3608 }
3609
system2000_init(struct romconfig * rc)3610 addrbank *system2000_init(struct romconfig *rc)
3611 {
3612 struct soft_scsi *scsi = getscsi(rc);
3613
3614 if (!scsi)
3615 return NULL;
3616 map_banks(scsi->bank, 0xf00000 >> 16, 0x10000 >> 16, 0);
3617 scsi->board_mask = 0xffff;
3618 scsi->baseaddress = 0xf00000;
3619 scsi->configured = 1;
3620 if (!rc->autoboot_disabled) {
3621 load_rom_rc(rc, ROMTYPE_SYSTEM2000, 16384, 0, scsi->rom, 16384, 0);
3622 }
3623 return scsi->bank;
3624 }
3625
system2000_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3626 void system2000_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3627 {
3628 generic_soft_scsi_add(ch, ci, rc, OMTI_SYSTEM2000, 65536, 16384, ROMTYPE_SYSTEM2000);
3629 }
3630
omtiadapter_init(struct romconfig * rc)3631 addrbank *omtiadapter_init(struct romconfig *rc)
3632 {
3633 struct soft_scsi *scsi = getscsi(rc);
3634
3635 if (!scsi)
3636 return NULL;
3637 map_banks(scsi->bank, 0x8f0000 >> 16, 0x10000 >> 16, 0);
3638 scsi->board_mask = 0xffff;
3639 scsi->baseaddress = 0x8f0000;
3640 scsi->configured = 1;
3641 return scsi->bank;
3642 }
3643
omtiadapter_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3644 void omtiadapter_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3645 {
3646 generic_soft_scsi_add(ch, ci, rc, OMTI_ADAPTER, 65536, 0, ROMTYPE_OMTIADAPTER);
3647 }
3648
x86_xt_hd_init(struct romconfig * rc)3649 addrbank *x86_xt_hd_init(struct romconfig *rc)
3650 {
3651 struct soft_scsi *scsi = getscsi(rc);
3652
3653 if (!scsi)
3654 return NULL;
3655 struct zfile *f = read_device_from_romconfig(rc, 0);
3656 x86_xt_ide_bios(f, rc);
3657 zfile_fclose(f);
3658 scsi->configured = 1;
3659 x86_hd_data = scsi;
3660 return NULL;
3661 }
3662
x86_add_xt_hd_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3663 void x86_add_xt_hd_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3664 {
3665 generic_soft_scsi_add(ch, ci, rc, OMTI_X86, 0, 0, ROMTYPE_X86_HD);
3666 }
3667
phoenixboard_init(struct romconfig * rc)3668 addrbank *phoenixboard_init(struct romconfig *rc)
3669 {
3670 struct soft_scsi *scsi = getscsi(rc);
3671
3672 if (!scsi)
3673 return NULL;
3674
3675 const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_PHOENIXB);
3676 load_rom_rc(rc, ROMTYPE_PHOENIXB, 8192, rc->autoboot_disabled ? 0 : 8192, scsi->rom, 16384, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
3677 load_rom_rc(rc, ROMTYPE_PHOENIXB, 16384, 16384, scsi->rom + 16384, 16384, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
3678 memcpy(scsi->acmemory, scsi->rom, sizeof scsi->acmemory);
3679
3680 return scsi->bank;
3681 }
3682
phoenixboard_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)3683 void phoenixboard_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
3684 {
3685 generic_soft_scsi_add(ch, ci, rc, NCR5380_PHOENIXBOARD, 65536, 32768, ROMTYPE_PHOENIXB);
3686 }
3687
3688