1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * NCR 53C9x
5 *
6 * (c) 2014 Toni Wilen
7 */
8 
9 #include "sysconfig.h"
10 #include "sysdeps.h"
11 
12 #ifdef NCR9X
13 
14 #define NCR_DEBUG 0
15 
16 #include "options.h"
17 #include "uae.h"
18 #include "uae/memory.h"
19 #include "rommgr.h"
20 #include "custom.h"
21 #include "newcpu.h"
22 #include "ncr9x_scsi.h"
23 #include "scsi.h"
24 #include "filesys.h"
25 #include "zfile.h"
26 #include "blkdev.h"
27 #include "cpuboard.h"
28 #include "flashrom.h"
29 #include "autoconf.h"
30 #include "qemuvga/qemuuaeglue.h"
31 #include "qemuvga/queue.h"
32 #include "qemuvga/scsi/scsi.h"
33 #include "qemuvga/scsi/esp.h"
34 #include "gui.h"
35 
36 #define FASTLANE_BOARD_SIZE (2 * 16777216)
37 #define FASTLANE_ROM_SIZE 32768
38 #define FASTLANE_HARDBITS 0x01000041
39 #define FASTLANE_RESETDMA 0x01000081
40 
41 /* NetBSD Fastlane definitions */
42 #define FLSC_HB_DISABLED	0x01
43 #define FLSC_HB_BUSID6		0x02
44 #define FLSC_HB_SEAGATE		0x04
45 #define FLSC_HB_SLOW		0x08
46 #define FLSC_HB_SYNCHRON	0x10
47 #define FLSC_HB_CREQ		0x20
48 #define FLSC_HB_IACT		0x40
49 #define FLSC_HB_MINT		0x80
50 
51 #define FLSC_PB_ESI		0x01
52 #define FLSC_PB_EDI		0x02
53 #define FLSC_PB_ENABLE_DMA	0x04
54 #define FLSC_PB_DMA_WRITE	0x08
55 #define FLSC_PB_LED		0x10
56 
57 #define OKTAGON_BOARD_SIZE 65536
58 #define OKTAGON_ROM_SIZE 32768
59 #define OKTAGON_ROM_OFFSET 0x100
60 
61 #define OKTAGON_ESP_ADDR 0x03000
62 #define OKTAGON_DMA_START 0x01000
63 #define OKTAGON_DMA_END 0x2000
64 #define OKTAGON_INTENA 0x8000
65 #define OKTAGON_EEPROM_SCL 0x8010
66 #define OKTAGON_EEPROM_SDA 0x8018
67 #define OKTAGON_EEPROM_SIZE 512
68 
69 #define MASOBOSHI_ESP_ADDR 0xfa00
70 #define MASOBOSHI_DMA_START 0xf900
71 #define MASOBOSHI_DMA_END 0xfa00
72 
73 #define DKB_BOARD_SIZE 131072
74 #define DKB_ROM_SIZE 32768
75 #define DKB_ROM_OFFSET 0x8000
76 
77 
78 struct ncr9x_state
79 {
80 	DeviceState devobject;
81 	SCSIDevice *scsid[8];
82 	SCSIBus scsibus;
83 	uae_u32 board_mask;
84 	uae_u32 board_mask2;
85 	uae_u8 *rom;
86 	uae_u8 acmemory[128];
87 	int configured;
88 	uaecptr baseaddress;
89 	uaecptr baseaddress2;
90 	uae_u32 expamem_hi;
91 	uae_u32 expamem_lo;
92 	bool enabled;
93 	int rom_start, rom_end, rom_offset;
94 	int io_start, io_end;
95 	addrbank *bank;
96 	bool chipirq, boardirq, boardirqlatch;
97 	bool intena;
98 	bool irq6;
99 	void (*irq_func)(struct ncr9x_state*);
100 	int led;
101 	uaecptr dma_ptr;
102 	int dma_cnt;
103 	int dma_delay;
104 	int dma_delay_val;
105 	uae_u8 states[16];
106 	struct romconfig *rc;
107 	struct ncr9x_state **self_ptr;
108 
109 	uae_u8 data;
110 	bool data_valid;
111 	void *eeprom;
112 	uae_u8 eeprom_data[512];
113 	bool romisoddonly;
114 	bool romisevenonly;
115 
116 	uae_u8 *fakedma_data_buf;
117 	int fakedma_data_size_allocated;
118 	int fakedma_data_size;
119 	int fakedma_data_offset;
120 	uae_u8 *fakedma_data_write_buffer;
121 };
122 
123 
124 
125 /*
126 	Blizzard SCSI Kit IV:
127 
128 	scsi: 0x8000
129 	dma: 0x10000
130 
131 	pa >>= 1;
132 	if (!bsc->sc_datain)
133 		pa |= 0x80000000;
134 	bsc->sc_dmabase[0x8000] = (u_int8_t)(pa >> 24);
135 	bsc->sc_dmabase[0] = (u_int8_t)(pa >> 24);
136 	bsc->sc_dmabase[0] = (u_int8_t)(pa >> 16);
137 	bsc->sc_dmabase[0] = (u_int8_t)(pa >> 8);
138 	bsc->sc_dmabase[0] = (u_int8_t)(pa);
139 
140 	Blizzard 2060:
141 
142 	scsi: 0x1ff00
143 	dma: 0x1fff0
144 
145 	bsc->sc_reg[0xe0] = BZTZSC_PB_LED;	LED
146 
147 	pa >>= 1;
148 	if (!bsc->sc_datain)
149 		pa |= 0x80000000;
150 	bsc->sc_dmabase[12] = (u_int8_t)(pa);
151 	bsc->sc_dmabase[8] = (u_int8_t)(pa >> 8);
152 	bsc->sc_dmabase[4] = (u_int8_t)(pa >> 16);
153 	bsc->sc_dmabase[0] = (u_int8_t)(pa >> 24);
154 
155 */
156 
157 #define MAX_NCR9X_UNITS 10
158 
159 static struct ncr9x_state *ncr_blizzard_scsi;
160 static struct ncr9x_state *ncr_fastlane_scsi[MAX_DUPLICATE_EXPANSION_BOARDS];
161 static struct ncr9x_state *ncr_oktagon2008_scsi[MAX_DUPLICATE_EXPANSION_BOARDS];
162 static struct ncr9x_state *ncr_masoboshi_scsi[MAX_DUPLICATE_EXPANSION_BOARDS];
163 static struct ncr9x_state *ncr_dkb1200_scsi;
164 static struct ncr9x_state *ncr_ematrix530_scsi;
165 static struct ncr9x_state *ncr_multievolution_scsi;
166 static struct ncr9x_state *ncr_golemfast_scsi[MAX_DUPLICATE_EXPANSION_BOARDS];
167 
168 static struct ncr9x_state *ncr_units[MAX_NCR9X_UNITS + 1];
169 
freescsi(SCSIDevice * scsi)170 static void freescsi(SCSIDevice *scsi)
171 {
172 	if (scsi) {
173 		free_scsi((struct scsi_data*)scsi->handle);
174 		xfree(scsi);
175 	}
176 }
177 
freencrunit(struct ncr9x_state * ncr)178 static void freencrunit(struct ncr9x_state *ncr)
179 {
180 	if (!ncr)
181 		return;
182 	for (int i = 0; i < MAX_NCR9X_UNITS; i++) {
183 		if (ncr_units[i] == ncr) {
184 			ncr_units[i] = NULL;
185 		}
186 	}
187 	for (int ch = 0; ch < 8; ch++) {
188 		freescsi(ncr->scsid[ch]);
189 		ncr->scsid[ch] = NULL;
190 	}
191 	xfree(ncr->rom);
192 	if (ncr->self_ptr)
193 		*ncr->self_ptr = NULL;
194 	xfree(ncr);
195 }
196 
allocscsi(struct ncr9x_state ** ncr,struct romconfig * rc,int ch)197 static struct ncr9x_state *allocscsi(struct ncr9x_state **ncr, struct romconfig *rc, int ch)
198 {
199 	struct ncr9x_state *scsi;
200 
201 	if (ch < 0) {
202 		freencrunit(*ncr);
203 		*ncr = NULL;
204 	}
205 	if ((*ncr) == NULL) {
206 		scsi = xcalloc(struct ncr9x_state, 1);
207 		for (int i = 0; i < MAX_NCR9X_UNITS; i++) {
208 			if (ncr_units[i] == NULL) {
209 				ncr_units[i] = scsi;
210 				if (rc)
211 					rc->unitdata = scsi;
212 				scsi->rc = rc;
213 				scsi->self_ptr = ncr;
214 				*ncr = scsi;
215 				return scsi;
216 			}
217 		}
218 	}
219 	return *ncr;
220 }
221 
getscsi(struct romconfig * rc)222 static struct ncr9x_state *getscsi(struct romconfig *rc)
223 {
224 	for (int i = 0; i < MAX_NCR9X_UNITS; i++) {
225 		if (ncr_units[i]) {
226 			struct ncr9x_state *ncr = ncr_units[i];
227 			if (ncr->rc == rc)
228 				return ncr;
229 		}
230 	}
231 	return NULL;
232 }
233 
ncr9x_rethink(void)234 void ncr9x_rethink(void)
235 {
236 	for (int i = 0; ncr_units[i]; i++) {
237 		if (ncr_units[i]->boardirq) {
238 			if (ncr_units[i]->irq6)
239 				INTREQ_0(0x8000 | 0x2000);
240 			else
241 				INTREQ_0(0x8000 | 0x0008);
242 			return;
243 		}
244 	}
245 }
246 
set_irq2(struct ncr9x_state * ncr)247 static void set_irq2(struct ncr9x_state *ncr)
248 {
249 	if (ncr->chipirq && !ncr->boardirq) {
250 		ncr->boardirq = true;
251 		ncr9x_rethink();
252 	}
253 	if (!ncr->chipirq && ncr->boardirq) {
254 		ncr->boardirq = false;
255 	}
256 }
257 
set_irq2_dkb1200(struct ncr9x_state * ncr)258 static void set_irq2_dkb1200(struct ncr9x_state *ncr)
259 {
260 	if (!(ncr->states[0] & 0x40))
261 		ncr->boardirq = false;
262 	if (ncr->chipirq && !ncr->boardirq && (ncr->states[0] & 0x40)) {
263 		ncr->boardirq = true;
264 		ncr9x_rethink();
265 	}
266 }
267 
set_irq2_oktagon(struct ncr9x_state * ncr)268 static void set_irq2_oktagon(struct ncr9x_state *ncr)
269 {
270 	if (!(ncr->states[0] & 0x80))
271 		ncr->boardirq = false;
272 	if (ncr->chipirq && !ncr->boardirq && (ncr->states[0] & 0x80)) {
273 		ncr->boardirq = true;
274 		ncr9x_rethink();
275 	}
276 }
277 
set_irq2_fastlane(struct ncr9x_state * ncr)278 static void set_irq2_fastlane(struct ncr9x_state *ncr)
279 {
280 	if (!ncr->chipirq || !(ncr->states[0] & FLSC_PB_ESI)) {
281 		ncr->states[0] |= FLSC_HB_MINT;
282 		ncr->boardirq = false;
283 		return;
284 	}
285 	ncr->states[0] |= FLSC_HB_CREQ;
286 	ncr->states[0] &= ~FLSC_HB_MINT;
287 	if (ncr->states[0] & FLSC_PB_ESI) {
288 		if (!ncr->boardirq) {
289 			ncr->boardirq = true;
290 			ncr9x_rethink();
291 		}
292 	}
293 }
294 
set_irq2_golemfast(struct ncr9x_state * ncr)295 static void set_irq2_golemfast(struct ncr9x_state *ncr)
296 {
297 }
298 
set_irq2_masoboshi(struct ncr9x_state * ncr)299 static void set_irq2_masoboshi(struct ncr9x_state *ncr)
300 {
301 	if (ncr->chipirq) {
302 		ncr->boardirqlatch = true;
303 		if (1 || ncr->intena) {
304 			ncr->boardirq = true;
305 			ncr9x_rethink();
306 #if NCR_DEBUG > 1
307 			write_log(_T("MASOBOSHI IRQ\n"));
308 #endif
309 		} else {
310 			ncr->boardirq = false;
311 		}
312 	} else {
313 		ncr->boardirq = false;
314 	}
315 }
316 
esp_irq_raise(qemu_irq irq)317 void esp_irq_raise(qemu_irq irq)
318 {
319 	struct ncr9x_state *ncr = (struct ncr9x_state*)irq;
320 	ncr->chipirq = true;
321 #if NCR_DEBUG > 1
322 	write_log(_T("NCR9X +IRQ\n"));
323 #endif
324 	ncr->irq_func(ncr);
325 }
esp_irq_lower(qemu_irq irq)326 void esp_irq_lower(qemu_irq irq)
327 {
328 	struct ncr9x_state *ncr = (struct ncr9x_state*)irq;
329 	ncr->chipirq = false;
330 #if NCR_DEBUG > 1
331 	write_log(_T("NCR9X -IRQ\n"));
332 #endif
333 	ncr->irq_func(ncr);
334 }
335 
fakedma_buffer_size(struct ncr9x_state * ncr,int size)336 static void fakedma_buffer_size(struct ncr9x_state *ncr, int size)
337 {
338 	size = (size + 1) & ~1;
339 	if (ncr->fakedma_data_size_allocated >= size)
340 		return;
341 	if (ncr->fakedma_data_buf)
342 		xfree(ncr->fakedma_data_buf);
343 	ncr->fakedma_data_buf = xmalloc(uae_u8, size);
344 	ncr->fakedma_data_size_allocated = size;
345 }
346 
347 /* Fake DMA */
348 
fake_dma_read_ematrix(void * opaque,uint8_t * buf,int len)349 static int fake_dma_read_ematrix(void *opaque, uint8_t *buf, int len)
350 {
351 	struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
352 	ncr->states[0] = 1;
353 	ncr->chipirq = true;
354 	set_irq2(ncr);
355 	ncr->fakedma_data_offset = 0;
356 	ncr->fakedma_data_write_buffer = buf;
357 	ncr->fakedma_data_size = len;
358 	fakedma_buffer_size(ncr, len);
359 	return 0;
360 }
fake_dma_write_ematrix(void * opaque,uint8_t * buf,int len)361 static int fake_dma_write_ematrix(void *opaque, uint8_t *buf, int len)
362 {
363 	struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
364 	ncr->states[0] = 1;
365 	ncr->chipirq = true;
366 	set_irq2(ncr);
367 	ncr->fakedma_data_offset = 0;
368 	fakedma_buffer_size(ncr, len);
369 	memcpy(ncr->fakedma_data_buf, buf, len);
370 	if (len & 1)
371 		ncr->fakedma_data_buf[len] = 0;
372 	ncr->fakedma_data_size = len;
373 	return 0;
374 }
375 
fake_dma_read(void * opaque,uint8_t * buf,int len)376 static int fake_dma_read(void *opaque, uint8_t *buf, int len)
377 {
378 	struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
379 	ncr->fakedma_data_offset = 0;
380 	ncr->fakedma_data_write_buffer = buf;
381 	ncr->fakedma_data_size = len;
382 	fakedma_buffer_size(ncr, len);
383 	return 0;
384 }
fake_dma_write(void * opaque,uint8_t * buf,int len)385 static int fake_dma_write(void *opaque, uint8_t *buf, int len)
386 {
387 	struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
388 	ncr->fakedma_data_offset = 0;
389 	fakedma_buffer_size(ncr, len);
390 	memcpy(ncr->fakedma_data_buf, buf, len);
391 	if (len & 1)
392 		ncr->fakedma_data_buf[len] = 0;
393 	ncr->fakedma_data_size = len;
394 	return 0;
395 }
396 
fake2_dma_read(void * opaque,uint8_t * buf,int len)397 static int fake2_dma_read(void *opaque, uint8_t *buf, int len)
398 {
399 	struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
400 	esp_dma_enable(ncr->devobject.lsistate, 0);
401 	if (ncr->data_valid) {
402 		*buf = ncr->data;
403 		ncr->data_valid = false;
404 	}
405 	return 1;
406 }
fake2_dma_write(void * opaque,uint8_t * buf,int len)407 static int fake2_dma_write(void *opaque, uint8_t *buf, int len)
408 {
409 	struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
410 	esp_dma_enable(ncr->devobject.lsistate, 0);
411 	if (!ncr->data_valid) {
412 		ncr->data = *buf;
413 		ncr->data_valid = true;
414 		return 1;
415 	}
416 	return 0;
417 }
418 
419 /* Following are true DMA */
420 
fastlane_dma_read(void * opaque,uint8_t * buf,int len)421 static int fastlane_dma_read(void *opaque, uint8_t *buf, int len)
422 {
423 	struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
424 	if (!(ncr->states[0] & FLSC_PB_DMA_WRITE)) {
425 		write_log(_T("fastlane_dma_read mismatched direction!\n"));
426 		return -1;
427 	}
428 	while (len > 0) {
429 		uae_u16 v = get_word(ncr->dma_ptr & ~1);
430 		*buf++ = v >> 8;
431 		len--;
432 		if (len > 0) {
433 			*buf++ = v;
434 			len--;
435 		}
436 		ncr->dma_ptr += 2;
437 	}
438 	return -1;
439 }
fastlane_dma_write(void * opaque,uint8_t * buf,int len)440 static int fastlane_dma_write(void *opaque, uint8_t *buf, int len)
441 {
442 	struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
443 	if (ncr->states[0] & FLSC_PB_DMA_WRITE) {
444 		write_log(_T("fastlane_dma_write mismatched direction!\n"));
445 		return -1;
446 	}
447 	while (len > 0) {
448 		uae_u16 v;
449 		v = *buf++;
450 		len--;
451 		v <<= 8;
452 		if (len > 0) {
453 			v |= *buf++;
454 			len--;
455 		}
456 		put_word(ncr->dma_ptr & ~1, v);
457 		ncr->dma_ptr += 2;
458 	}
459 	return -1;
460 }
461 
cyberstorm_mk1_mk2_dma_read(void * opaque,uint8_t * buf,int len)462 static int cyberstorm_mk1_mk2_dma_read(void *opaque, uint8_t *buf, int len)
463 {
464 	struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
465 	if (!(ncr->dma_ptr & 0x00000001)) {
466 		write_log(_T("cyberstorm_dma_read mismatched direction!\n"));
467 		return -1;
468 	}
469 	while (len > 0) {
470 		uae_u16 v = get_word(ncr->dma_ptr & ~1);
471 		*buf++ = v >> 8;
472 		len--;
473 		if (len > 0) {
474 			*buf++ = v;
475 			len--;
476 		}
477 		ncr->dma_ptr += 2;
478 	}
479 	return -1;
480 }
cyberstorm_mk1_mk2_dma_write(void * opaque,uint8_t * buf,int len)481 static int cyberstorm_mk1_mk2_dma_write(void *opaque, uint8_t *buf, int len)
482 {
483 	struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
484 	if (ncr->dma_ptr & 0x00000001) {
485 		write_log(_T("cyberstorm_dma_write mismatched direction!\n"));
486 		return -1;
487 	}
488 	while (len > 0) {
489 		uae_u16 v;
490 		v = *buf++;
491 		len--;
492 		v <<= 8;
493 		if (len > 0) {
494 			v |= *buf++;
495 			len--;
496 		}
497 		put_word(ncr->dma_ptr & ~1, v);
498 		ncr->dma_ptr += 2;
499 	}
500 	return -1;
501 }
502 
blizzard_dma_read(void * opaque,uint8_t * buf,int len)503 static int blizzard_dma_read(void *opaque, uint8_t *buf, int len)
504 {
505 	struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
506 	if (!(ncr->dma_ptr & 0x80000000)) {
507 		write_log(_T("blizzard_dma_read mismatched direction!\n"));
508 		return -1;
509 	}
510 	while (len > 0) {
511 		uae_u16 v = get_word((ncr->dma_ptr & 0x7fffffff) * 2);
512 		*buf++ = v >> 8;
513 		len--;
514 		if (len > 0) {
515 			*buf++ = v;
516 			len--;
517 		}
518 		ncr->dma_ptr++;
519 	}
520 	return -1;
521 }
blizzard_dma_write(void * opaque,uint8_t * buf,int len)522 static int blizzard_dma_write(void *opaque, uint8_t *buf, int len)
523 {
524 	struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
525 	if (ncr->dma_ptr & 0x80000000) {
526 		write_log(_T("blizzard_dma_write mismatched direction!\n"));
527 		return -1;
528 	}
529 	while (len > 0) {
530 		uae_u16 v;
531 		v = *buf++;
532 		len--;
533 		v <<= 8;
534 		if (len > 0) {
535 			v |= *buf++;
536 			len--;
537 		}
538 		put_word((ncr->dma_ptr & 0x7fffffff) * 2, v);
539 		ncr->dma_ptr++;
540 	}
541 	return -1;
542 }
543 
get_scb_len(uae_u8 cmd)544 static int get_scb_len(uae_u8 cmd)
545 {
546 	if (cmd <= 0x1f)
547 		return 6;
548 	if (cmd >= 0x20 && cmd <= 0x5f)
549 		return 10;
550 	if (cmd >= 0x80 && cmd <= 0x9f)
551 		return 16;
552 	if (cmd >= 0xa0 && cmd <= 0xbf)
553 		return 12;
554 	return 0;
555 }
556 
scsiesp_req_continue(SCSIRequest * req)557 void scsiesp_req_continue(SCSIRequest *req)
558 {
559 	struct scsi_data *sd = (struct scsi_data*)req->dev->handle;
560 	if (sd->data_len < 0) {
561 		esp_command_complete(req, sd->status, 0);
562 	} else if (sd->data_len) {
563 		esp_transfer_data(req, sd->data_len);
564 	} else {
565 		if (sd->direction > 0)
566 			scsi_emulate_cmd(sd);
567 		esp_command_complete(req, sd->status, 0);
568 	}
569 }
scsiesp_req_new(SCSIDevice * d,uint32_t tag,uint32_t lun,uint8_t * buf,void * hba_private)570 SCSIRequest *scsiesp_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun, uint8_t *buf, void *hba_private)
571 {
572 	SCSIRequest *req = xcalloc(SCSIRequest, 1);
573 	struct scsi_data *sd = (struct scsi_data*)d->handle;
574 	struct ncr9x_state *ncr = (struct ncr9x_state*)sd->privdata;
575 	int len = get_scb_len(buf[0]);
576 
577 	req->dev = d;
578 	req->hba_private = hba_private;
579 	req->bus = &ncr->scsibus;
580 	req->bus->qbus.parent = &ncr->devobject;
581 
582 	memcpy(sd->cmd, buf, len);
583 	sd->cmd_len = len;
584 	return req;
585 }
scsiesp_req_enqueue(SCSIRequest * req)586 int32_t scsiesp_req_enqueue(SCSIRequest *req)
587 {
588 	struct scsi_data *sd = (struct scsi_data*)req->dev->handle;
589 
590 	if (sd->device_type == UAEDEV_CD)
591 		gui_flicker_led (LED_CD, sd->id, 1);
592 
593 	sd->data_len = 0;
594 	scsi_start_transfer(sd);
595 	scsi_emulate_analyze(sd);
596 #if 0
597 	write_log (_T("%02x.%02x.%02x.%02x.%02x.%02x\n"), sd->cmd[0], sd->cmd[1], sd->cmd[2], sd->cmd[3], sd->cmd[4], sd->cmd[5]);
598 #endif
599 	if (sd->direction <= 0)
600 		scsi_emulate_cmd(sd);
601 	if (sd->direction == 0)
602 		return 1;
603 	if (sd->direction > 0)
604 		return -sd->data_len;
605 	return sd->data_len;
606 }
scsiesp_req_unref(SCSIRequest * req)607 void scsiesp_req_unref(SCSIRequest *req)
608 {
609 	xfree(req);
610 }
scsiesp_req_get_buf(SCSIRequest * req)611 uint8_t *scsiesp_req_get_buf(SCSIRequest *req)
612 {
613 	struct scsi_data *sd = (struct scsi_data*)req->dev->handle;
614 	sd->data_len = 0;
615 	return sd->buffer;
616 }
scsiesp_device_find(SCSIBus * bus,int channel,int target,int lun)617 SCSIDevice *scsiesp_device_find(SCSIBus *bus, int channel, int target, int lun)
618 {
619 	struct ncr9x_state *ncr = (struct ncr9x_state*)bus->privdata;
620 	if (lun != 0 || target < 0 || target >= 8)
621 		return NULL;
622 	return ncr->scsid[target];
623 }
scsiesp_req_cancel(SCSIRequest * req)624 void scsiesp_req_cancel(SCSIRequest *req)
625 {
626 	write_log(_T("scsi_req_cancel\n"));
627 }
628 
629 #define IO_MASK 0x3f
630 
beswap(uaecptr addr)631 static uaecptr beswap(uaecptr addr)
632 {
633 	return (addr & ~3) | (3 - (addr & 3));
634 }
635 
isncr(struct ncr9x_state * ncr,struct ncr9x_state ** arr)636 static bool isncr(struct ncr9x_state *ncr, struct ncr9x_state **arr)
637 {
638 	for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) {
639 		if (arr[i] == ncr)
640 			return true;
641 	}
642 	return false;
643 }
644 
ncr9x_io_bput(struct ncr9x_state * ncr,uaecptr addr,uae_u32 val)645 static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val)
646 {
647 	int reg_shift = 2;
648 	uaecptr oldaddr = addr;
649 
650 	addr &= ncr->board_mask;
651 	if (ncr == ncr_multievolution_scsi) {
652 		reg_shift = 1;
653 		if (addr & 0x1000) {
654 			if (ncr->fakedma_data_offset < ncr->fakedma_data_size) {
655 				ncr->fakedma_data_buf[ncr->fakedma_data_offset++] = val;
656 				if (ncr->fakedma_data_offset == ncr->fakedma_data_size) {
657 					memcpy(ncr->fakedma_data_write_buffer, ncr->fakedma_data_buf, ncr->fakedma_data_size);
658 					esp_fake_dma_done(ncr->devobject.lsistate);
659 				}
660 			}
661 			return;
662 		}
663 	} else if (isncr(ncr, ncr_golemfast_scsi)) {
664 
665 		reg_shift = 1;
666 		if ((addr & 0x8400) == 0x8400) {
667 			if (ncr->fakedma_data_offset < ncr->fakedma_data_size) {
668 				ncr->fakedma_data_buf[ncr->fakedma_data_offset++] = val;
669 				if (ncr->fakedma_data_offset == ncr->fakedma_data_size) {
670 					memcpy(ncr->fakedma_data_write_buffer, ncr->fakedma_data_buf, ncr->fakedma_data_size);
671 					esp_fake_dma_done(ncr->devobject.lsistate);
672 				}
673 			}
674 			return;
675 		}
676 
677 	} else if (isncr(ncr, ncr_masoboshi_scsi)) {
678 
679 		if (addr >= 0xf040 && addr < 0xf048) {
680 			if (addr == 0xf040)
681 				ncr->states[8] = 0;
682 			if (addr == 0xf047) {
683 				// dma start
684 				if (val & 0x80) {
685 					write_log(_T("MASOBOSHI DMA start %08x, %d\n"), ncr->dma_ptr, ncr->dma_cnt);
686 					ncr->dma_delay = (ncr->dma_cnt / maxhpos) * 2;
687 					ncr->dma_delay_val = -1;
688 				} else {
689 					ncr->dma_delay = 0;
690 				}
691 			}
692 			return;
693 		}
694 
695 		// DMA LEN (words)
696 		if (addr >= 0xf04a && addr < 0xf04c) {
697 			if (addr == 0xf04a) {
698 				ncr->dma_cnt &= 0x00ff;
699 				ncr->dma_cnt |= val << 8;
700 			} else {
701 				ncr->dma_cnt &= 0xff00;
702 				ncr->dma_cnt |= val;
703 			}
704 			return;
705 		}
706 
707 		// DMA PTR
708 		if (addr >= 0xf04c && addr < 0xf050) {
709 			int shift = (addr - 0xf04c) * 8;
710 			uae_u32 mask = 0xff << shift;
711 			ncr->dma_ptr &= ~mask;
712 			ncr->dma_ptr |= val << shift;
713 			ncr->dma_ptr &= 0xffffff;
714 			return;
715 		}
716 
717 		if (addr >= 0xf000 && addr <= 0xf007) {
718 			ncr->states[addr - 0xf000] = val;
719 			if (addr == 0xf000) {
720 				ncr->boardirqlatch = false;
721 				set_irq2_masoboshi(ncr);
722 			}
723 #if 0
724 			if (addr == 0xf007) {
725 				ncr->intena = true;//(val & 8) == 0;
726 				ncr9x_rethink();
727 			}
728 #endif
729 #if 0
730 			if (addr == 0xf047) { // dma start
731 				if (val & 0x80)
732 					ncr->states[2] = 0x80;
733 			}
734 			if (addr == 0xf040) {
735 				ncr->states[2] = 0;
736 			}
737 #endif
738 #if 0
739 			write_log(_T("MASOBOSHI IO %08X PUT %02x %08x\n"), addr, val & 0xff, M68K_GETPC);
740 #endif
741 			return;
742 		}
743 
744 		if (addr >= MASOBOSHI_DMA_START && addr < MASOBOSHI_DMA_END) {
745 			if (esp_reg_read(ncr->devobject.lsistate, ESP_RSTAT) & STAT_TC) {
746 #if NCR_DEBUG > 2
747 				write_log(_T("MASOBOSHI DMA OVERFLOW %08X PUT %02x %08x\n"), addr, val & 0xff, M68K_GETPC);
748 #endif
749 			} else {
750 				ncr->data = val;
751 				ncr->data_valid = true;
752 				esp_dma_enable(ncr->devobject.lsistate, 1);
753 #if NCR_DEBUG > 2
754 				write_log(_T("MASOBOSHI DMA %08X PUT %02x %08x\n"), addr, val & 0xff, M68K_GETPC);
755 #endif
756 			}
757 			return;
758 		}
759 		if (addr < MASOBOSHI_ESP_ADDR || addr >= MASOBOSHI_ESP_ADDR + 0x100) {
760 #if NCR_DEBUG
761 			write_log(_T("MASOBOSHI IO %08X PUT %02x %08x\n"), addr, val & 0xff, M68K_GETPC);
762 #endif
763 			return;
764 		}
765 		if (addr == MASOBOSHI_ESP_ADDR + 3 * 2 && val == 0x02)
766 			ncr->states[0] |= 0x80;
767 		reg_shift = 1;
768 		addr &= 0x3f;
769 
770 	} else if (isncr(ncr, ncr_oktagon2008_scsi)) {
771 		if (addr == OKTAGON_EEPROM_SCL) {
772 			eeprom_i2c_set(ncr->eeprom, BITBANG_I2C_SCL, (val & 0x80) != 0);
773 		} else if (addr == OKTAGON_EEPROM_SDA) {
774 			eeprom_i2c_set(ncr->eeprom, BITBANG_I2C_SDA, (val & 0x80) != 0);
775 		} else if (addr >= OKTAGON_DMA_START && addr < OKTAGON_DMA_END) {
776 			ncr->data = val;
777 			ncr->data_valid = true;
778 			esp_dma_enable(ncr->devobject.lsistate, 1);
779 			return;
780 		} else if (addr == OKTAGON_INTENA) {
781 			ncr->states[0] = val;
782 			set_irq2_oktagon(ncr);
783 			return;
784 		}
785 		if (addr < OKTAGON_ESP_ADDR || addr >= OKTAGON_ESP_ADDR + 0x100) {
786 			return;
787 		}
788 		reg_shift = 1;
789 	} else if (isncr(ncr, ncr_fastlane_scsi)) {
790 		if (addr >= FASTLANE_HARDBITS) {
791 			if (addr == FASTLANE_HARDBITS) {
792 				int oldstate = ncr->states[0];
793 				ncr->states[0] = val;
794 				if (!(oldstate & FLSC_PB_ENABLE_DMA) && (ncr->states[0] & FLSC_PB_ENABLE_DMA))
795 					esp_dma_enable(ncr->devobject.lsistate, 1);
796 				else if ((oldstate & FLSC_PB_ENABLE_DMA) && !(ncr->states[0] & FLSC_PB_ENABLE_DMA))
797 					esp_dma_enable(ncr->devobject.lsistate, 0);
798 				set_irq2_fastlane(ncr);
799 			} else if (addr == FASTLANE_RESETDMA) {
800 				ncr->dma_cnt = 4;
801 				ncr->dma_ptr = 0;
802 			}
803 			return;
804 		} else if (addr < 0x01000000) {
805 			addr &= 3;
806 			addr = 3 - addr;
807 			ncr->dma_ptr &= ~(0xff << (addr * 8));
808 			ncr->dma_ptr |= (val & 0xff) << (addr * 8);
809 			ncr->dma_cnt--;
810 			if (ncr->dma_cnt == 0 && (ncr->states[0] & FLSC_PB_ENABLE_DMA))
811 				esp_dma_enable(ncr->devobject.lsistate, 1);
812 			return;
813 		}
814 	} else if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_2060)) {
815 		if (addr >= BLIZZARD_2060_DMA_OFFSET) {
816 			//write_log (_T("Blizzard DMA PUT %08x %02X\n"), addr, (uae_u8)val);
817 			addr &= 0xf;
818 			addr >>= 2;
819 			addr = 3 - addr;
820 
821 			ncr->dma_ptr &= ~(0xff << (addr * 8));
822 			ncr->dma_ptr |= (val & 0xff) << (addr * 8);
823 			if (addr == 3)
824 				esp_dma_enable(ncr->devobject.lsistate, 1);
825 			return;
826 		} else if (addr >= BLIZZARD_2060_LED_OFFSET) {
827 			ncr->led = val;
828 			return;
829 		}
830 	} else if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230IV) || ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1260)) {
831 		if (!cfgfile_board_enabled(&currprefs, ROMTYPE_BLIZKIT4, 0))
832 			return;
833 		if (addr >= BLIZZARD_SCSI_KIT_DMA_OFFSET) {
834 			addr &= 0x18000;
835 			if (addr == 0x18000) {
836 				ncr->dma_ptr = 0;
837 				ncr->dma_cnt = 4;
838 			} else {
839 				ncr->dma_ptr <<= 8;
840 				ncr->dma_ptr |= (uae_u8)val;
841 				ncr->dma_cnt--;
842 				if (ncr->dma_cnt == 0)
843 					esp_dma_enable(ncr->devobject.lsistate, 1);
844 			}
845 			//write_log(_T("Blizzard DMA PUT %08x %02X\n"), oldaddr, (uae_u8)val);
846 			return;
847 		}
848 	} else if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK1)) {
849 		if (addr >= CYBERSTORM_MK1_JUMPER_OFFSET) {
850 			if (addr == CYBERSTORM_MK1_JUMPER_OFFSET)
851 				esp_dma_enable(ncr->devobject.lsistate, 1);
852 		} else if (addr >= CYBERSTORM_MK1_DMA_OFFSET) {
853 			addr &= 7;
854 			addr >>= 1;
855 			addr = 3 - addr;
856 			ncr->dma_ptr &= ~(0xff << (addr * 8));
857 			ncr->dma_ptr |= (val & 0xff) << (addr * 8);
858 			return;
859 		} else if (addr >= CYBERSTORM_MK2_LED_OFFSET) {
860 			ncr->led = val;
861 			return;
862 		}
863 	} else if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK2)) {
864 		if (addr >= CYBERSTORM_MK2_DMA_OFFSET) {
865 			addr &= 0xf;
866 			addr >>= 2;
867 			addr = 3 - addr;
868 			ncr->dma_ptr &= ~(0xff << (addr * 8));
869 			ncr->dma_ptr |= (val & 0xff) << (addr * 8);
870 			if (addr == 0)
871 				esp_dma_enable(ncr->devobject.lsistate, 1);
872 			return;
873 		 } else if (addr >= CYBERSTORM_MK2_LED_OFFSET) {
874 			 ncr->led = val;
875 			 return;
876 		 }
877 	} else if (ISCPUBOARD(BOARD_DKB, BOARD_DKB_SUB_12x0)) {
878 		if (addr == 0x10100) {
879 			ncr->states[0] = val;
880 			esp_dma_enable(ncr->devobject.lsistate, 1);
881 			//write_log(_T("DKB IO PUT %02x %08x\n"), val & 0xff, M68K_GETPC);
882 			return;
883 		}
884 		if (addr >= 0x10080 && addr < 0x10088) {
885 			//write_log(_T("DKB PUT BYTE %02x\n"), val & 0xff);
886 			if (ncr->fakedma_data_offset < ncr->fakedma_data_size) {
887 				ncr->fakedma_data_buf[ncr->fakedma_data_offset++] = val;
888 				if (ncr->fakedma_data_offset == ncr->fakedma_data_size) {
889 					memcpy(ncr->fakedma_data_write_buffer, ncr->fakedma_data_buf, ncr->fakedma_data_size);
890 					esp_fake_dma_done(ncr->devobject.lsistate);
891 				}
892 			}
893 			return;
894 		}
895 		if (addr < 0x10000 || addr >= 0x10040) {
896 			write_log(_T("DKB IO %08X PUT %02x %08x\n"), addr, val & 0xff, M68K_GETPC);
897 			return;
898 		}
899 	} else if (ISCPUBOARD(BOARD_MTEC, BOARD_MTEC_SUB_EMATRIX530)) {
900 		if ((addr & 0xf000) >= 0xe000) {
901 			if ((addr & 0x3ff) <= 7) {
902 				if (ncr->fakedma_data_offset < ncr->fakedma_data_size) {
903 					ncr->fakedma_data_buf[ncr->fakedma_data_offset++] = val;
904 					if (ncr->fakedma_data_offset == ncr->fakedma_data_size) {
905 						memcpy(ncr->fakedma_data_write_buffer, ncr->fakedma_data_buf, ncr->fakedma_data_size);
906 						esp_fake_dma_done(ncr->devobject.lsistate);
907 						ncr->states[0] = 0;
908 					}
909 				}
910 			}
911 			return;
912 		}
913 		if (addr < 0xc000 || addr >= 0xe000)
914 			return;
915  		if (addr & 1)
916 			return;
917 		if (currprefs.cpuboard_settings & 1)
918 			return;
919 		reg_shift = 3;
920 	}
921 	if (!ncr->devobject.lsistate)
922 		return;
923 	addr >>= reg_shift;
924 	addr &= IO_MASK;
925 #if NCR_DEBUG > 1
926 	write_log(_T("ESP write %02X (%08X) %02X %08X\n"), addr, oldaddr, val & 0xff, M68K_GETPC);
927 #endif
928 	esp_reg_write(ncr->devobject.lsistate, (addr), val);
929 }
930 
ncr9x_io_bget(struct ncr9x_state * ncr,uaecptr addr)931 static uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr)
932 {
933 	uae_u8 v = 0xff;
934 	int reg_shift = 2;
935 	uaecptr oldaddr = addr;
936 
937 	addr &= ncr->board_mask;
938 
939 	if (ncr == ncr_multievolution_scsi) {
940 
941 		reg_shift = 1;
942 		if (addr & 0x1000) {
943 			if (ncr->fakedma_data_offset >= ncr->fakedma_data_size)
944 				return 0;
945 			v = ncr->fakedma_data_buf[ncr->fakedma_data_offset++];
946 			if (ncr->fakedma_data_offset == ncr->fakedma_data_size) {
947 				esp_fake_dma_done(ncr->devobject.lsistate);
948 				//write_log(_T("MultiEvolution fake dma finished\n"));
949 			}
950 			//write_log(_T("MultiEvolution fake dma %02x %d/%d\n"), v, ncr->fakedma_data_offset, ncr->fakedma_data_size);
951 			return v;
952 		}
953 
954 	} else if (isncr(ncr, ncr_golemfast_scsi)) {
955 
956 		reg_shift = 1;
957 		if ((addr & 0x8400) == 0x8400) {
958 			if (ncr->fakedma_data_offset >= ncr->fakedma_data_size)
959 				return 0;
960 			v = ncr->fakedma_data_buf[ncr->fakedma_data_offset++];
961 			if (ncr->fakedma_data_offset == ncr->fakedma_data_size) {
962 				esp_fake_dma_done(ncr->devobject.lsistate);
963 			}
964 			//write_log(_T("FAKEDMA READ %08x %02X %08x (%d/%d)\n"), addr, v, M68K_GETPC, ncr->fakedma_data_offset, ncr->fakedma_data_size);
965 			return v;
966 		}
967 
968 	} else if (isncr(ncr, ncr_masoboshi_scsi)) {
969 
970 		if (addr == MASOBOSHI_ESP_ADDR + 3 * 2 && (ncr->states[0] & 0x80))
971 			return 2;
972 		if (ncr->states[0] & 0x80)
973 			ncr->states[0] &= ~0x80;
974 
975 		if (addr == 0xf040) {
976 
977 			if (ncr->dma_delay > 0) {
978 				if (vpos != ncr->dma_delay_val) {
979 					ncr->dma_delay--;
980 					ncr->dma_delay_val = vpos;
981 					if (!ncr->dma_delay) {
982 						ncr->states[8] = 0x80;
983 					}
984 				}
985 			}
986 			v = ncr->states[8];
987 			return v;
988 		}
989 
990 		if (addr >= 0xf04c && addr < 0xf050) {
991 			int shift = (addr - 0xf04c) * 8;
992 			uae_u32 mask = 0xff << shift;
993 			if (addr == 0xf04f)
994 				write_log(_T("MASOBOSHI DMA PTR READ = %08x %08x\n"), ncr->dma_ptr, M68K_GETPC);
995 			return ncr->dma_ptr >> shift;
996 		}
997 		if (addr >= 0xf048 && addr < 0xf04c) {
998 			write_log(_T("MASOBOSHI DMA %08X GET %02x %08x\n"), addr, v, M68K_GETPC);
999 			return v;
1000 		}
1001 		if (addr >= 0xf000 && addr <= 0xf007) {
1002 			int idx = addr - 0xf000;
1003 			if (addr == 0xf000) {
1004 				ncr->states[0] |= 2;
1005 				ncr->states[0] |= 1;
1006 				if (esp_dreq(&ncr->devobject)) {
1007 					ncr->states[0] &= ~1; // data request
1008 				}
1009 				if (ncr->boardirqlatch) {
1010 					ncr->states[0] &= ~2; // scsi interrupt
1011 				}
1012 #if 0
1013 				if (ncr->chipirq) {
1014 					ncr->states[0] &= ~1;
1015 				}
1016 #endif
1017 			}
1018 			v = ncr->states[idx];
1019 #if 0
1020 			write_log(_T("MASOBOSHI IO %08X GET %02x %08x\n"), addr, v, M68K_GETPC);
1021 #endif
1022 			return v;
1023 		}
1024 #if 0
1025 		if (addr == 0xf007) {
1026 			v = ncr->states[0];
1027 		}
1028 #endif
1029 		if (addr >= MASOBOSHI_DMA_START && addr < MASOBOSHI_DMA_END) {
1030 			esp_dma_enable(ncr->devobject.lsistate, 1);
1031 			v = ncr->data;
1032 			ncr->data_valid = false;
1033 #if NCR_DEBUG > 2
1034 			write_log(_T("MASOBOSHI DMA %08X GET %02x %08x\n"), addr, v, M68K_GETPC);
1035 #endif
1036 			return v;
1037 		}
1038 		if (addr < MASOBOSHI_ESP_ADDR || addr >= MASOBOSHI_ESP_ADDR + 0x100) {
1039 #if NCR_DEBUG
1040 			write_log(_T("MASOBOSHI IO %08X GET %02x %08x\n"), addr, v, M68K_GETPC);
1041 #endif
1042 			return v;
1043 		}
1044 		reg_shift = 1;
1045 		addr &= 0x3f;
1046 
1047 	} else if (isncr(ncr, ncr_oktagon2008_scsi)) {
1048 		if (addr == OKTAGON_EEPROM_SCL) {
1049 			return eeprom_i2c_set(ncr->eeprom, BITBANG_I2C_SCL, -1) ? 0x80 : 0x00;
1050 		} else if (addr == OKTAGON_EEPROM_SDA) {
1051 			return eeprom_i2c_set(ncr->eeprom, BITBANG_I2C_SDA, -1) ? 0x80 : 0x00;
1052 		} else if (addr >= OKTAGON_DMA_START && addr < OKTAGON_DMA_END) {
1053 			esp_dma_enable(ncr->devobject.lsistate, 1);
1054 			v = ncr->data;
1055 			ncr->data_valid = false;
1056 			return v;
1057 		} else if (addr == OKTAGON_INTENA) {
1058 			return ncr->states[0];
1059 		}
1060 		if (addr < OKTAGON_ESP_ADDR || addr >= OKTAGON_ESP_ADDR + 0x100)
1061 			return 0xff;
1062 		reg_shift = 1;
1063 	} else if (isncr(ncr, ncr_fastlane_scsi)) {
1064 		if (addr >= FASTLANE_HARDBITS) {
1065 			if (addr == FASTLANE_HARDBITS) {
1066 				uae_u8 v = ncr->states[0];
1067 				v &= ~(FLSC_HB_DISABLED | FLSC_HB_BUSID6 | FLSC_HB_SEAGATE | FLSC_HB_SLOW | FLSC_HB_SYNCHRON);
1068 				return v;
1069 			}
1070 			return 0;
1071 		}
1072 	} else if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_2060)) {
1073 		if (addr >= BLIZZARD_2060_DMA_OFFSET) {
1074 			write_log(_T("Blizzard DMA GET %08x\n"), addr);
1075 			return 0;
1076 		} else if (addr >= BLIZZARD_2060_LED_OFFSET) {
1077 			return ncr->led;
1078 		}
1079 	} else if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230IV) || ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1260)) {
1080 		if (!cfgfile_board_enabled(&currprefs, ROMTYPE_BLIZKIT4, 0))
1081 			return 0;
1082 		if (addr >= BLIZZARD_SCSI_KIT_DMA_OFFSET)
1083 			return 0;
1084 	} else if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK1)) {
1085 		if (addr >= CYBERSTORM_MK1_JUMPER_OFFSET) {
1086 			return 0xff;
1087 		} else if (addr >= CYBERSTORM_MK1_DMA_OFFSET) {
1088 			return 0;
1089 		} else if (addr >= CYBERSTORM_MK1_LED_OFFSET) {
1090 			return ncr->led;
1091 		}
1092 	} else if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK2)) {
1093 		if (addr >= CYBERSTORM_MK2_DMA_OFFSET) {
1094 			return 0;
1095 		} else if (addr >= CYBERSTORM_MK2_LED_OFFSET) {
1096 			return ncr->led;
1097 		}
1098 	} else if (ISCPUBOARD(BOARD_DKB, BOARD_DKB_SUB_12x0)) {
1099 		if (addr == 0x10100) {
1100 			uae_u8 v = 0;
1101 			if (ncr->chipirq || ncr->boardirq)
1102 				v |= 0x40;
1103 			if (ncr->fakedma_data_offset < ncr->fakedma_data_size)
1104 				v |= 0x80;
1105 			ncr->boardirq = false;
1106 			//write_log(_T("DKB IO GET %02x %08x\n"), v, M68K_GETPC);
1107 			return v;
1108 		}
1109 		if (addr >= 0x10080 && addr < 0x10088) {
1110 			//write_log(_T("DKB GET BYTE %02x\n"), ncr->fakedma_data_buf[ncr->fakedma_data_offset]);
1111 			if (ncr->fakedma_data_offset >= ncr->fakedma_data_size)
1112 				return 0;
1113 			v = ncr->fakedma_data_buf[ncr->fakedma_data_offset++];
1114 			if (ncr->fakedma_data_offset == ncr->fakedma_data_size) {
1115 				esp_fake_dma_done(ncr->devobject.lsistate);
1116 				//write_log(_T("DKB fake dma finished\n"));
1117 			}
1118 			return v;
1119 		}
1120 		if (addr < 0x10000 || addr >= 0x10040) {
1121 			write_log(_T("DKB IO GET %08x %08x\n"), addr, M68K_GETPC);
1122 			return 0;
1123 		}
1124 	} else if (ISCPUBOARD(BOARD_MTEC, BOARD_MTEC_SUB_EMATRIX530)) {
1125 		if ((addr & 0xf000) >= 0xe000) {
1126 			if ((addr & 0x3ff) <= 7) {
1127 				if (ncr->fakedma_data_offset >= ncr->fakedma_data_size) {
1128 					ncr->states[0] = 0;
1129 					return 0;
1130 				}
1131 				v = ncr->fakedma_data_buf[ncr->fakedma_data_offset++];
1132 				if (ncr->fakedma_data_offset == ncr->fakedma_data_size) {
1133 					esp_fake_dma_done(ncr->devobject.lsistate);
1134 					ncr->states[0] = 0;
1135 				}
1136 				return v;
1137 			}
1138 			return 0xff;
1139 		}
1140 		if ((addr & 1) && !(addr & 0x0800)) {
1141 			// dma request
1142 			return ncr->states[0] ? 0xff : 0x7f;
1143 		}
1144 		if ((addr & 1) && (addr & 0x0800)) {
1145 			// hardware revision?
1146 			return 0x7f;
1147 		}
1148 		if (addr & 1)
1149 			return 0x7f;
1150 		if (currprefs.cpuboard_settings & 1)
1151 			return 0x7f;
1152 		if (addr < 0xc000 || addr >= 0xe000)
1153 			return 0x7f;
1154 		reg_shift = 3;
1155 	}
1156 	if (!ncr->devobject.lsistate)
1157 		return v;
1158 	addr >>= reg_shift;
1159 	addr &= IO_MASK;
1160 	v = esp_reg_read(ncr->devobject.lsistate, (addr));
1161 #if NCR_DEBUG > 1
1162 	write_log(_T("ESP read %02X (%08X) %02X %08X\n"), addr, oldaddr, v, M68K_GETPC);
1163 #endif
1164 	return v;
1165 }
1166 
read_rombyte(struct ncr9x_state * ncr,uaecptr addr)1167 static uae_u8 read_rombyte(struct ncr9x_state *ncr, uaecptr addr)
1168 {
1169 	uae_u8 v = ncr->rom[addr];
1170 #if 0
1171 	if (addr == 0x104)
1172 		activate_debugger();
1173 #endif
1174 	return v;
1175 }
1176 
ncr9x_bget2(struct ncr9x_state * ncr,uaecptr addr)1177 static uae_u32 ncr9x_bget2(struct ncr9x_state *ncr, uaecptr addr)
1178 {
1179 	uae_u32 v = 0;
1180 
1181 	addr &= ncr->board_mask;
1182 	if (ncr->rom && addr >= ncr->rom_start && addr < ncr->rom_end) {
1183 		if (addr < ncr->io_start || (!ncr->romisoddonly && !ncr->romisevenonly) || (ncr->romisoddonly && (addr & 1)) || (ncr->romisevenonly && (addr & 1)))
1184 			return read_rombyte (ncr, addr - ncr->rom_offset);
1185 	}
1186 	if (ncr->io_end && (addr < ncr->io_start || addr >= ncr->io_end))
1187 		return v;
1188 	return ncr9x_io_bget(ncr, addr);
1189 }
1190 
ncr9x_bput2(struct ncr9x_state * ncr,uaecptr addr,uae_u32 val)1191 static void ncr9x_bput2(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val)
1192 {
1193 	uae_u32 v = val;
1194 	addr &= ncr->board_mask;
1195 	if (ncr->io_end && (addr < ncr->io_start || addr >= ncr->io_end))
1196 		return;
1197 	ncr9x_io_bput(ncr, addr, val);
1198 }
1199 
ncr9x_lget(struct ncr9x_state * ncr,uaecptr addr)1200 static uae_u32 REGPARAM2 ncr9x_lget(struct ncr9x_state *ncr, uaecptr addr)
1201 {
1202 	uae_u32 v;
1203 	addr &= ncr->board_mask;
1204 	if (isncr(ncr, ncr_oktagon2008_scsi)) {
1205 		v =  ncr9x_io_bget(ncr, addr + 0) << 24;
1206 		v |= ncr9x_io_bget(ncr, addr + 1) << 16;
1207 		v |= ncr9x_io_bget(ncr, addr + 2) <<  8;
1208 		v |= ncr9x_io_bget(ncr, addr + 3) <<  0;
1209 	} else {
1210 		v =  ncr9x_bget2(ncr, addr + 0) << 24;
1211 		v |= ncr9x_bget2(ncr, addr + 1) << 16;
1212 		v |= ncr9x_bget2(ncr, addr + 2) <<  8;
1213 		v |= ncr9x_bget2(ncr, addr + 3) <<  0;
1214 	}
1215 	return v;
1216 }
1217 
ncr9x_wget(struct ncr9x_state * ncr,uaecptr addr)1218 static uae_u32 REGPARAM2 ncr9x_wget(struct ncr9x_state *ncr, uaecptr addr)
1219 {
1220 	uae_u32 v;
1221 	addr &= ncr->board_mask;
1222 	if (isncr(ncr, ncr_oktagon2008_scsi)) {
1223 		v = ncr9x_io_bget(ncr, addr) << 8;
1224 		v |= ncr9x_io_bget(ncr, addr + 1);
1225 	} else {
1226 		v = ncr9x_bget2(ncr, addr) << 8;
1227 		v |= ncr9x_bget2(ncr, addr + 1);
1228 	}
1229 	return v;
1230 }
1231 
ncr9x_bget(struct ncr9x_state * ncr,uaecptr addr)1232 static uae_u32 REGPARAM2 ncr9x_bget(struct ncr9x_state *ncr, uaecptr addr)
1233 {
1234 	uae_u32 v;
1235 	addr &= ncr->board_mask;
1236 	if (!ncr->configured) {
1237 		addr &= 65535;
1238 		if (addr >= sizeof ncr->acmemory)
1239 			return 0;
1240 		return ncr->acmemory[addr];
1241 	}
1242 	v = ncr9x_bget2(ncr, addr);
1243 	return v;
1244 }
1245 
ncr9x_lput(struct ncr9x_state * ncr,uaecptr addr,uae_u32 l)1246 static void REGPARAM2 ncr9x_lput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 l)
1247 {
1248 	addr &= ncr->board_mask;
1249 	if (isncr(ncr, ncr_oktagon2008_scsi)) {
1250 		ncr9x_io_bput(ncr, addr + 0, l >> 24);
1251 		ncr9x_io_bput(ncr, addr + 1, l >> 16);
1252 		ncr9x_io_bput(ncr, addr + 2, l >>  8);
1253 		ncr9x_io_bput(ncr, addr + 3, l >>  0);
1254 	} else {
1255 		ncr9x_bput2(ncr, addr + 0, l >> 24);
1256 		ncr9x_bput2(ncr, addr + 1, l >> 16);
1257 		ncr9x_bput2(ncr, addr + 2, l >>  8);
1258 		ncr9x_bput2(ncr, addr + 3, l >>  0);
1259 	}
1260 }
1261 
ncr9x_wput(struct ncr9x_state * ncr,uaecptr addr,uae_u32 w)1262 static void REGPARAM2 ncr9x_wput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 w)
1263 {
1264 	w &= 0xffff;
1265 	addr &= ncr->board_mask;
1266 	if (!ncr->configured) {
1267 		addr &= 65535;
1268 		switch (addr)
1269 		{
1270 			case 0x44:
1271 			map_banks_z3(ncr->bank, expamem_z3_pointer >> 16, FASTLANE_BOARD_SIZE >> 16);
1272 			ncr->baseaddress = expamem_z3_pointer;
1273 			ncr->configured = 1;
1274 			expamem_next (ncr->bank, NULL);
1275 			break;
1276 		}
1277 		return;
1278 	}
1279 	if (isncr(ncr, ncr_oktagon2008_scsi)) {
1280 		ncr9x_io_bput(ncr, addr, w >> 8);
1281 		ncr9x_io_bput(ncr, addr + 1, w);
1282 	} else {
1283 		ncr9x_bput2(ncr, addr, w >> 8);
1284 		ncr9x_bput2(ncr, addr + 1, w);
1285 	}
1286 }
1287 
ncr9x_bput(struct ncr9x_state * ncr,uaecptr addr,uae_u32 b)1288 static void REGPARAM2 ncr9x_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 b)
1289 {
1290 	b &= 0xff;
1291 	addr &= ncr->board_mask;
1292 	if (!ncr->configured) {
1293 		addr &= 65535;
1294 		switch (addr)
1295 		{
1296 			case 0x48:
1297 			if (isncr(ncr, ncr_fastlane_scsi))
1298 				return;
1299 			map_banks_z2(ncr->bank, expamem_z2_pointer >> 16, expamem_z2_size >> 16);
1300 			ncr->configured = 1;
1301 			ncr->baseaddress = expamem_z2_pointer;
1302 			expamem_next (ncr->bank, NULL);
1303 			break;
1304 			case 0x4c:
1305 			ncr->configured = 1;
1306 			expamem_shutup(ncr->bank);
1307 			break;
1308 		}
1309 		return;
1310 	}
1311 	ncr9x_bput2(ncr, addr, b);
1312 }
1313 
getscsiboard(uaecptr addr)1314 static struct ncr9x_state *getscsiboard(uaecptr addr)
1315 {
1316 	for (int i = 0; ncr_units[i]; i++) {
1317 		if (!ncr_units[i]->baseaddress)
1318 			return ncr_units[i];
1319 		if ((addr & ~ncr_units[i]->board_mask) == ncr_units[i]->baseaddress)
1320 			return ncr_units[i];
1321 		if (ncr_units[i]->baseaddress2 && (addr & ~ncr_units[i]->board_mask2) == ncr_units[i]->baseaddress2)
1322 			return ncr_units[i];
1323 	}
1324 	return NULL;
1325 }
1326 
ncr9x_generic_bput(uaecptr addr,uae_u32 b)1327 static void REGPARAM2 ncr9x_generic_bput (uaecptr addr, uae_u32 b)
1328 {
1329 	struct ncr9x_state *ncr = getscsiboard(addr);
1330 	if (ncr)
1331 		ncr9x_bput(ncr, addr, b);
1332 }
ncr9x_generic_wput(uaecptr addr,uae_u32 b)1333 static void REGPARAM2 ncr9x_generic_wput (uaecptr addr, uae_u32 b)
1334 {
1335 	struct ncr9x_state *ncr = getscsiboard(addr);
1336 	if (ncr)
1337 		ncr9x_wput(ncr, addr, b);
1338 }
ncr9x_generic_lput(uaecptr addr,uae_u32 b)1339 static void REGPARAM2 ncr9x_generic_lput (uaecptr addr, uae_u32 b)
1340 {
1341 	struct ncr9x_state *ncr = getscsiboard(addr);
1342 	if (ncr)
1343 		ncr9x_lput(ncr, addr, b);
1344 }
ncr9x_generic_bget(uaecptr addr)1345 static uae_u32 REGPARAM2 ncr9x_generic_bget (uaecptr addr)
1346 {
1347 	struct ncr9x_state *ncr = getscsiboard(addr);
1348 	if (ncr)
1349 		return ncr9x_bget(ncr, addr);
1350 	return 0;
1351 }
ncr9x_generic_wget(uaecptr addr)1352 static uae_u32 REGPARAM2 ncr9x_generic_wget (uaecptr addr)
1353 {
1354 	struct ncr9x_state *ncr = getscsiboard(addr);
1355 	if (ncr)
1356 		return ncr9x_wget(ncr, addr);
1357 	return 0;
1358 }
ncr9x_generic_lget(uaecptr addr)1359 static uae_u32 REGPARAM2 ncr9x_generic_lget (uaecptr addr)
1360 {
1361 	struct ncr9x_state *ncr = getscsiboard(addr);
1362 	if (ncr)
1363 		return ncr9x_lget(ncr, addr);
1364 	return 0;
1365 }
ncr9x_generic_xlate(uaecptr addr)1366 static uae_u8 *REGPARAM2 ncr9x_generic_xlate(uaecptr addr)
1367 {
1368 	struct ncr9x_state *ncr = getscsiboard(addr);
1369 	if (!ncr)
1370 		return NULL;
1371 	addr &= ncr->board_mask;
1372 	return ncr->rom + addr;
1373 
1374 }
ncr9x_generic_check(uaecptr a,uae_u32 b)1375 static int REGPARAM2 ncr9x_generic_check(uaecptr a, uae_u32 b)
1376 {
1377 	struct ncr9x_state *ncr = getscsiboard(a);
1378 	if (!ncr)
1379 		return 0;
1380 	a &= ncr->board_mask;
1381 	if (a >= ncr->rom_start && a + b < ncr->rom_end)
1382 		return 1;
1383 	return 0;
1384 }
1385 
1386 static addrbank ncr9x_bank_generic = {
1387 	ncr9x_generic_lget, ncr9x_generic_wget, ncr9x_generic_bget,
1388 	ncr9x_generic_lput, ncr9x_generic_wput, ncr9x_generic_bput,
1389 	ncr9x_generic_xlate, ncr9x_generic_check, NULL, NULL, _T("53C94/FAS216"),
1390 	ncr9x_generic_lget, ncr9x_generic_wget,
1391 	ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
1392 };
1393 
cpuboard_ncr9x_scsi_get(uaecptr addr)1394 uae_u32 cpuboard_ncr9x_scsi_get(uaecptr addr)
1395 {
1396 	return ncr9x_io_bget(ncr_blizzard_scsi, addr);
1397 }
cpuboard_ncr9x_scsi_put(uaecptr addr,uae_u32 v)1398 void cpuboard_ncr9x_scsi_put(uaecptr addr, uae_u32 v)
1399 {
1400 	ncr9x_io_bput(ncr_blizzard_scsi, addr, v);
1401 }
1402 
masoboshi_ncr9x_scsi_get(uaecptr addr,int devnum)1403 uae_u32 masoboshi_ncr9x_scsi_get(uaecptr addr, int devnum)
1404 {
1405 	return ncr9x_io_bget(ncr_masoboshi_scsi[devnum], addr);
1406 }
masoboshi_ncr9x_scsi_put(uaecptr addr,uae_u32 v,int devnum)1407 void masoboshi_ncr9x_scsi_put(uaecptr addr, uae_u32 v, int devnum)
1408 {
1409 	ncr9x_io_bput(ncr_masoboshi_scsi[devnum], addr, v);
1410 }
1411 
golemfast_ncr9x_scsi_get(uaecptr addr,int devnum)1412 uae_u32 golemfast_ncr9x_scsi_get(uaecptr addr, int devnum)
1413 {
1414 	return ncr9x_io_bget(ncr_golemfast_scsi[devnum], addr);
1415 }
golemfast_ncr9x_scsi_put(uaecptr addr,uae_u32 v,int devnum)1416 void golemfast_ncr9x_scsi_put(uaecptr addr, uae_u32 v, int devnum)
1417 {
1418 	ncr9x_io_bput(ncr_golemfast_scsi[devnum], addr, v);
1419 }
1420 
ew(struct ncr9x_state * ncr,int addr,uae_u8 value)1421 static void ew(struct ncr9x_state *ncr, int addr, uae_u8 value)
1422 {
1423 	if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
1424 		ncr->acmemory[addr] = (value & 0xf0);
1425 		ncr->acmemory[addr + 2] = (value & 0x0f) << 4;
1426 	} else {
1427 		ncr->acmemory[addr] = ~(value & 0xf0);
1428 		ncr->acmemory[addr + 2] = ~((value & 0x0f) << 4);
1429 	}
1430 }
1431 
ncr9x_reset_board(struct ncr9x_state * ncr)1432 static void ncr9x_reset_board(struct ncr9x_state *ncr)
1433 {
1434 	if (!ncr)
1435 		return;
1436 	ncr->configured = 0;
1437 	ncr->boardirq = false;
1438 	ncr->chipirq = false;
1439 }
1440 
ncr9x_reset(void)1441 void ncr9x_reset(void)
1442 {
1443 	for (int i = 0; ncr_units[i]; i++) {
1444 		ncr9x_reset_board(ncr_units[i]);
1445 		ncr_units[i]->enabled = false;
1446 	}
1447 }
1448 
ncr_golemfast_autoconfig_init(struct romconfig * rc,uaecptr baseaddress)1449 void ncr_golemfast_autoconfig_init(struct romconfig *rc, uaecptr baseaddress)
1450 {
1451 	struct ncr9x_state *ncr = getscsi(rc);
1452 
1453 	if (!ncr)
1454 		return;
1455 
1456 	ncr->enabled = true;
1457 	ncr->baseaddress = baseaddress;
1458 
1459 	ncr9x_reset_board(ncr);
1460 }
1461 
ncr_multievolution_init(struct romconfig * rc)1462 addrbank *ncr_multievolution_init(struct romconfig *rc)
1463 {
1464 	struct ncr9x_state *ncr = getscsi(rc);
1465 
1466 	xfree(ncr->rom);
1467 	ncr->rom = NULL;
1468 
1469 	if (!ncr)
1470 		return &expamem_null;
1471 
1472 	ncr->bank = &ncr9x_bank_generic;
1473 	ncr->enabled = true;
1474 	ncr->rom = xcalloc(uae_u8, 65536);
1475 
1476 	ncr->configured = -1;
1477 	ncr->board_mask = 0x1ffff;
1478 	ncr->board_mask2 = 0xffff;
1479 	ncr->baseaddress = 0xf00000;
1480 	ncr->baseaddress2 = 0xef0000;
1481 	ncr->rom_start = 0;
1482 	ncr->rom_offset = 0;
1483 	ncr->rom_end = 0x10000;
1484 	ncr->io_start = 0x1e000;
1485 	ncr->io_end = ncr->io_start + 0x2000;
1486 	ncr->irq6 = true;
1487 
1488 	load_rom_rc(rc, ROMTYPE_MEVOLUTION, 65536, 0, ncr->rom, 65536, 0);
1489 
1490 	map_banks(ncr->bank, ncr->baseaddress2 >> 16, (ncr->board_mask + 1) >> 16, 0);
1491 
1492 	return &expamem_null;
1493 }
1494 
ncr_fastlane_autoconfig_init(struct romconfig * rc)1495 addrbank *ncr_fastlane_autoconfig_init(struct romconfig *rc)
1496 {
1497 	struct ncr9x_state *ncr = getscsi(rc);
1498 
1499 	xfree(ncr->rom);
1500 	ncr->rom = NULL;
1501 
1502 	if (!ncr)
1503 		return &expamem_null;
1504 
1505 	ncr->enabled = true;
1506 	memset (ncr->acmemory, 0xff, sizeof ncr->acmemory);
1507 	ncr->rom_start = 0x800;
1508 	ncr->rom_offset = 0;
1509 	ncr->rom_end = FASTLANE_ROM_SIZE * 4;
1510 	ncr->io_start = 0;
1511 	ncr->io_end = 0;
1512 	ncr->bank = &ncr9x_bank_generic;
1513 
1514 	ncr9x_reset_board(ncr);
1515 
1516 	struct zfile *z = read_device_from_romconfig(rc, ROMTYPE_FASTLANE);
1517 	ncr->rom = xcalloc (uae_u8, FASTLANE_ROM_SIZE * 4);
1518 	if (z) {
1519 		// memory board at offset 0x100
1520 		int autoconfig_offset = 0;
1521 		memset(ncr->rom, 0xff, FASTLANE_ROM_SIZE * 4);
1522 		for (int i = 0; i < FASTLANE_ROM_SIZE; i++) {
1523 			int ia = i - autoconfig_offset;
1524 			uae_u8 b;
1525 			zfile_fread (&b, 1, 1, z);
1526 			ncr->rom[i * 4 + 0] = b | 0x0f;
1527 			ncr->rom[i * 4 + 2] = (b << 4) | 0x0f;
1528 			if (ia >= 0 && ia < 0x20) {
1529 				ncr->acmemory[ia * 4 + 0] = b;
1530 			} else if (ia >= 0x40 && ia < 0x60) {
1531 				ncr->acmemory[(ia - 0x40) * 4 + 2] = b;
1532 			}
1533 		}
1534 		zfile_fclose(z);
1535 	}
1536 
1537 	return ncr->bank;
1538 }
1539 
1540 static const uae_u8 oktagon_autoconfig[16] = {
1541 	0xd1, 0x05, 0x00, 0x00, 0x08, 0x2c, 0x00, 0x00, 0x00, 0x00, OKTAGON_ROM_OFFSET >> 8, OKTAGON_ROM_OFFSET & 0xff
1542 };
1543 
1544 // Only offsets 0x100 to 0x10f contains non-FF data
1545 static const uae_u8 oktagon_eeprom[16] =
1546 {
1547 	0x0b, 0xf4, 0x3f, 0x0a, 0xff, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xaf, 0xff
1548 };
1549 
ncr_oktagon_autoconfig_init(struct romconfig * rc)1550 addrbank *ncr_oktagon_autoconfig_init(struct romconfig *rc)
1551 {
1552 	struct ncr9x_state *ncr = getscsi(rc);
1553 
1554 	if (!ncr)
1555 		return &expamem_null;
1556 
1557 	xfree(ncr->rom);
1558 	ncr->rom = NULL;
1559 	eeprom_free(ncr->eeprom);
1560 	ncr->eeprom = NULL;
1561 
1562 	ncr->enabled = true;
1563 	memset (ncr->acmemory, 0xff, sizeof ncr->acmemory);
1564 	ncr->rom_start = 0;
1565 	ncr->rom_offset = 0;
1566 	ncr->rom_end = OKTAGON_ROM_SIZE * 2;
1567 	ncr->io_start = 0x2000;
1568 	ncr->io_end = ncr->rom_end;
1569 	ncr->romisoddonly = true;
1570 	ncr->bank = &ncr9x_bank_generic;
1571 
1572 	memset(ncr->eeprom_data, 0xff, OKTAGON_EEPROM_SIZE);
1573 	memcpy(ncr->eeprom_data + 0x100, oktagon_eeprom, 16);
1574 	ncr->eeprom = eeprom_new(ncr->eeprom_data, OKTAGON_EEPROM_SIZE, NULL);
1575 	ncr->rom = xcalloc (uae_u8, OKTAGON_ROM_SIZE * 6);
1576 	memset(ncr->rom, 0xff, OKTAGON_ROM_SIZE * 6);
1577 
1578 	ncr9x_reset_board(ncr);
1579 
1580 	if (!rc->autoboot_disabled) {
1581 		struct zfile *z = read_device_from_romconfig(rc, ROMTYPE_OKTAGON);
1582 		if (z) {
1583 			// memory board at offset 0x100
1584 			memset(ncr->rom, 0xff, OKTAGON_ROM_SIZE * 4);
1585 			for (int i = 0; i < 0x1000 / 2; i++) {
1586 				uae_u8 b;
1587 				zfile_fread(&b, 1, 1, z);
1588 				ncr->rom[OKTAGON_ROM_OFFSET + i * 4 + 0] = b;
1589 				zfile_fread(&b, 1, 1, z);
1590 				ncr->rom[OKTAGON_ROM_OFFSET + i * 4 + 2] = b;
1591 			}
1592 			for (int i = 0; i < OKTAGON_ROM_SIZE - 0x1000; i++) {
1593 				uae_u8 b;
1594 				zfile_fread(&b, 1, 1, z);
1595 				ncr->rom[0x2000 + i * 4 + 1] = b;
1596 				zfile_fread(&b, 1, 1, z);
1597 				ncr->rom[0x2000 + i * 4 + 3] = b;
1598 			}
1599 			zfile_fclose(z);
1600 		}
1601 	}
1602 	for (int i = 0; i < 16; i++) {
1603 		uae_u8 b = oktagon_autoconfig[i];
1604 		ew(ncr, i * 4, b);
1605 	}
1606 
1607 	return ncr->bank;
1608 }
1609 
1610 
ncr_dkb_autoconfig_init(struct romconfig * rc)1611 addrbank *ncr_dkb_autoconfig_init(struct romconfig *rc)
1612 {
1613 	struct ncr9x_state *ncr = getscsi(rc);
1614 
1615 	if (!ncr)
1616 		return &expamem_null;
1617 
1618 	xfree(ncr->rom);
1619 	ncr->rom = NULL;
1620 
1621 	ncr->enabled = true;
1622 	memset (ncr->acmemory, 0xff, sizeof ncr->acmemory);
1623 	ncr->rom_start = 0;
1624 	ncr->rom_offset = 0;
1625 	ncr->rom_end = DKB_ROM_SIZE * 2;
1626 	ncr->io_start = 0x10000;
1627 	ncr->io_end = 0x20000;
1628 	ncr->bank = &ncr9x_bank_generic;
1629 	ncr->board_mask = 131071;
1630 
1631 	ncr9x_reset_board(ncr);
1632 
1633 	struct zfile *z = read_device_from_romconfig(rc, ROMTYPE_CB_DKB12x0);
1634 	ncr->rom = xcalloc (uae_u8, DKB_ROM_SIZE * 2);
1635 	if (z) {
1636 		// memory board at offset 0x100
1637 		int i;
1638 		memset(ncr->rom, 0xff, DKB_ROM_SIZE * 2);
1639 
1640 		zfile_fseek(z, 0, SEEK_SET);
1641 		for (i = 0; i < (sizeof ncr->acmemory) / 2; i++) {
1642 			uae_u8 b;
1643 			zfile_fread(&b, 1, 1, z);
1644 			ncr->acmemory[i * 2] = b;
1645 		}
1646 		for (;;) {
1647 			uae_u8 b;
1648 			if (!zfile_fread(&b, 1, 1, z))
1649 				break;
1650 			ncr->rom[i * 2] = b;
1651 			i++;
1652 		}
1653 		zfile_fclose(z);
1654 	}
1655 
1656 	return ncr->bank;
1657 }
1658 
ncr_ematrix_autoconfig_init(struct romconfig * rc)1659 addrbank *ncr_ematrix_autoconfig_init(struct romconfig *rc)
1660 {
1661 	struct ncr9x_state *ncr = getscsi(rc);
1662 
1663 	if (!ncr)
1664 		return &expamem_null;
1665 
1666 	xfree(ncr->rom);
1667 	ncr->rom = NULL;
1668 
1669 	ncr->enabled = true;
1670 	memset(ncr->acmemory, 0xff, sizeof ncr->acmemory);
1671 	ncr->rom_start = 0;
1672 	ncr->rom_offset = 0;
1673 	ncr->rom_end = 0x8000;
1674 	ncr->io_start = 0x8000;
1675 	ncr->io_end = 0x10000;
1676 	ncr->bank = &ncr9x_bank_generic;
1677 	ncr->board_mask = 65535;
1678 
1679 	ncr9x_reset_board(ncr);
1680 
1681 	struct zfile *z = read_device_from_romconfig(rc, ROMTYPE_CB_EMATRIX);
1682 	ncr->rom = xcalloc(uae_u8, 65536);
1683 	if (z) {
1684 		int i;
1685 		memset(ncr->rom, 0xff, 65536);
1686 
1687 		zfile_fseek(z, 32768, SEEK_SET);
1688 		for (i = 0; i < (sizeof ncr->acmemory) / 2; i++) {
1689 			uae_u8 b;
1690 			zfile_fread(&b, 1, 1, z);
1691 			ncr->acmemory[i * 2] = b;
1692 		}
1693 		for (;;) {
1694 			uae_u8 b;
1695 			if (!zfile_fread(&b, 1, 1, z))
1696 				break;
1697 			ncr->rom[i * 2] = b;
1698 			i++;
1699 		}
1700 		zfile_fclose(z);
1701 	}
1702 
1703 	return ncr->bank;
1704 }
1705 
ncr_masoboshi_autoconfig_init(struct romconfig * rc,uaecptr baseaddress)1706 void ncr_masoboshi_autoconfig_init(struct romconfig *rc, uaecptr baseaddress)
1707 {
1708 	struct ncr9x_state *ncr = getscsi(rc);
1709 
1710 	if (!ncr)
1711 		return;
1712 
1713 	ncr->enabled = true;
1714 	ncr->baseaddress = baseaddress;
1715 
1716 	ncr9x_reset_board(ncr);
1717 }
1718 
ncr9x_esp_scsi_init(struct ncr9x_state * ncr,ESPDMAMemoryReadWriteFunc read,ESPDMAMemoryReadWriteFunc write,void (* irq_func)(struct ncr9x_state *))1719 static void ncr9x_esp_scsi_init(struct ncr9x_state *ncr, ESPDMAMemoryReadWriteFunc read, ESPDMAMemoryReadWriteFunc write, void (*irq_func)(struct ncr9x_state*))
1720 {
1721 	ncr->board_mask = 0xffff;
1722 	ncr->irq_func = irq_func ? irq_func : set_irq2;
1723 	if (!ncr->devobject.lsistate)
1724 		esp_scsi_init(&ncr->devobject, read, write);
1725 	esp_scsi_reset(&ncr->devobject, ncr);
1726 }
1727 
ncr9x_free(void)1728 void ncr9x_free(void)
1729 {
1730 	for (int i = 0; ncr_units[i]; i++) {
1731 		freencrunit(ncr_units[i]);
1732 	}
1733 }
1734 
ncr9x_init(void)1735 void ncr9x_init(void)
1736 {
1737 }
1738 
allocscsidevice(struct ncr9x_state * ncr,int ch,struct scsi_data * handle)1739 static void allocscsidevice(struct ncr9x_state *ncr, int ch, struct scsi_data *handle)
1740 {
1741 	handle->privdata = ncr;
1742 	ncr->scsid[ch] = xcalloc (SCSIDevice, 1);
1743 	ncr->scsid[ch]->id = ch;
1744 	ncr->scsid[ch]->handle = handle;
1745 }
1746 
add_ncr_scsi_hd(struct ncr9x_state * ncr,int ch,struct hd_hardfiledata * hfd,struct uaedev_config_info * ci)1747 static void add_ncr_scsi_hd(struct ncr9x_state *ncr, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci)
1748 {
1749 	struct scsi_data *handle = NULL;
1750 
1751 	freescsi(ncr->scsid[ch]);
1752 	ncr->scsid[ch] = NULL;
1753 	if (!add_scsi_hd(&handle, ch, hfd, ci))
1754 		return;
1755 	allocscsidevice(ncr, ch, handle);
1756 	ncr->enabled = true;
1757 }
1758 
add_ncr_scsi_cd(struct ncr9x_state * ncr,int ch,int unitnum)1759 static void add_ncr_scsi_cd(struct ncr9x_state *ncr, int ch, int unitnum)
1760 {
1761 	struct scsi_data *handle = NULL;
1762 
1763 	freescsi(ncr->scsid[ch]);
1764 	ncr->scsid[ch] = NULL;
1765 	if (!add_scsi_cd(&handle, ch, unitnum))
1766 		return;
1767 	allocscsidevice(ncr, ch, handle);
1768 	ncr->enabled = true;
1769 }
1770 
add_ncr_scsi_tape(struct ncr9x_state * ncr,int ch,const TCHAR * tape_directory,bool readonly)1771 static void add_ncr_scsi_tape(struct ncr9x_state *ncr, int ch, const TCHAR *tape_directory, bool readonly)
1772 {
1773 	struct scsi_data *handle = NULL;
1774 
1775 	freescsi(ncr->scsid[ch]);
1776 	ncr->scsid[ch] = NULL;
1777 	if (!add_scsi_tape(&handle, ch, tape_directory, readonly))
1778 		return;
1779 	allocscsidevice(ncr, ch, handle);
1780 	ncr->enabled = true;
1781 }
1782 
ncr9x_add_scsi_unit(struct ncr9x_state ** ncrp,int ch,struct uaedev_config_info * ci,struct romconfig * rc)1783 static void ncr9x_add_scsi_unit(struct ncr9x_state **ncrp, int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1784 {
1785 	struct ncr9x_state *ncr = allocscsi(ncrp, rc, ch);
1786 	if (ch >= 0 && ncr) {
1787 		if (ci->type == UAEDEV_CD)
1788 			add_ncr_scsi_cd (ncr, ch, ci->device_emu_unit);
1789 		else if (ci->type == UAEDEV_TAPE)
1790 			add_ncr_scsi_tape (ncr, ch, ci->rootdir, ci->readonly);
1791 		else if (ci->type == UAEDEV_HDF)
1792 			add_ncr_scsi_hd (ncr, ch, NULL, ci);
1793 	}
1794 }
1795 
cpuboard_ncr9x_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1796 void cpuboard_ncr9x_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1797 {
1798 	ncr9x_add_scsi_unit(&ncr_blizzard_scsi, ch, ci, rc);
1799 	ncr_blizzard_scsi->configured = -1;
1800 	ncr_blizzard_scsi->enabled = true;
1801 	if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK1) || ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK2)) {
1802 		ncr9x_esp_scsi_init(ncr_blizzard_scsi, cyberstorm_mk1_mk2_dma_read, cyberstorm_mk1_mk2_dma_write, NULL);
1803 	} else {
1804 		ncr9x_esp_scsi_init(ncr_blizzard_scsi, blizzard_dma_read, blizzard_dma_write, NULL);
1805 	}
1806 	if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK1))
1807 		ncr_blizzard_scsi->board_mask = 0xffff;
1808 	else
1809 		ncr_blizzard_scsi->board_mask = 0x1ffff;
1810 }
1811 
cpuboard_dkb_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1812 void cpuboard_dkb_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1813 {
1814 	ncr9x_add_scsi_unit(&ncr_dkb1200_scsi, ch, ci, rc);
1815 	ncr9x_esp_scsi_init(ncr_dkb1200_scsi, fake_dma_read, fake_dma_write, set_irq2_dkb1200);
1816 }
1817 
fastlane_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1818 void fastlane_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1819 {
1820 	ncr9x_add_scsi_unit(&ncr_fastlane_scsi[ci->controller_type_unit], ch, ci, rc);
1821 	ncr9x_esp_scsi_init(ncr_fastlane_scsi[ci->controller_type_unit], fastlane_dma_read, fastlane_dma_write, set_irq2_fastlane);
1822 	ncr_fastlane_scsi[ci->controller_type_unit]->board_mask = 32 * 1024 * 1024 - 1;
1823 }
1824 
oktagon_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1825 void oktagon_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1826 {
1827 	ncr9x_add_scsi_unit(&ncr_oktagon2008_scsi[ci->controller_type_unit], ch, ci, rc);
1828 	ncr9x_esp_scsi_init(ncr_oktagon2008_scsi[ci->controller_type_unit], fake2_dma_read, fake2_dma_write, set_irq2_oktagon);
1829 }
1830 
masoboshi_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1831 void masoboshi_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1832 {
1833 	ncr9x_add_scsi_unit(&ncr_masoboshi_scsi[ci->controller_type_unit], ch, ci, rc);
1834 	ncr9x_esp_scsi_init(ncr_masoboshi_scsi[ci->controller_type_unit], fake2_dma_read, fake2_dma_write, set_irq2_masoboshi);
1835 }
1836 
ematrix_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1837 void ematrix_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1838 {
1839 	ncr9x_add_scsi_unit(&ncr_ematrix530_scsi, ch, ci, rc);
1840 	ncr9x_esp_scsi_init(ncr_ematrix530_scsi, fake_dma_read_ematrix, fake_dma_write_ematrix, set_irq2);
1841 	esp_dma_enable(ncr_ematrix530_scsi->devobject.lsistate, 1);
1842 }
1843 
multievolution_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1844 void multievolution_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1845 {
1846 	ncr9x_add_scsi_unit(&ncr_multievolution_scsi, ch, ci, rc);
1847 	ncr9x_esp_scsi_init(ncr_multievolution_scsi, fake_dma_read, fake_dma_write, set_irq2);
1848 	esp_dma_enable(ncr_multievolution_scsi->devobject.lsistate, 1);
1849 }
1850 
golemfast_add_scsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1851 void golemfast_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1852 {
1853 	ncr9x_add_scsi_unit(&ncr_golemfast_scsi[ci->controller_type_unit], ch, ci, rc);
1854 	ncr9x_esp_scsi_init(ncr_golemfast_scsi[ci->controller_type_unit], fake_dma_read, fake_dma_write, set_irq2_golemfast);
1855 	esp_dma_enable(ncr_golemfast_scsi[ci->controller_type_unit]->devobject.lsistate, 1);
1856 }
1857 
1858 #endif
1859