1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * Other IDE controllers
5 *
6 * (c) 2015 Toni Wilen
7 */
8 
9 #include "sysconfig.h"
10 #include "sysdeps.h"
11 
12 #include "options.h"
13 
14 #include "memory.h"
15 #include "newcpu.h"
16 #include "uae.h"
17 #include "gui.h"
18 #include "filesys.h"
19 #include "threaddep/thread.h"
20 #include "debug.h"
21 #include "ide.h"
22 #include "idecontrollers.h"
23 #include "zfile.h"
24 #include "custom.h"
25 #include "rommgr.h"
26 #include "cpuboard.h"
27 #include "scsi.h"
28 #include "ncr9x_scsi.h"
29 #include "autoconf.h"
30 
31 #define DEBUG_IDE 0
32 #define DEBUG_IDE_GVP 0
33 #define DEBUG_IDE_ALF 0
34 #define DEBUG_IDE_APOLLO 0
35 #define DEBUG_IDE_MASOBOSHI 0
36 
37 #define GVP_IDE 0 // GVP A3001
38 #define ALF_IDE 1
39 #define APOLLO_IDE (ALF_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
40 #define MASOBOSHI_IDE (APOLLO_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
41 #define ADIDE_IDE (MASOBOSHI_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
42 #define MTEC_IDE (ADIDE_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
43 #define PROTAR_IDE (MTEC_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
44 #define ROCHARD_IDE (PROTAR_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
45 #define x86_AT_IDE (ROCHARD_IDE + 2 * MAX_DUPLICATE_EXPANSION_BOARDS)
46 #define GOLEMFAST_IDE (x86_AT_IDE + 2 * MAX_DUPLICATE_EXPANSION_BOARDS)
47 #define TOTAL_IDE (GOLEMFAST_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
48 
49 #define ALF_ROM_OFFSET 0x0100
50 #define GVP_IDE_ROM_OFFSET 0x8000
51 #define APOLLO_ROM_OFFSET 0x8000
52 #define ADIDE_ROM_OFFSET 0x8000
53 #define MASOBOSHI_ROM_OFFSET 0x0080
54 #define MASOBOSHI_ROM_OFFSET_END 0xf000
55 #define MASOBOSHI_SCSI_OFFSET 0xf800
56 #define MASOBOSHI_SCSI_OFFSET_END 0xfc00
57 
58 /* masoboshi:
59 
60 IDE
61 
62 - FFCC = base address, data (0)
63 - FF81 = -004B
64 - FF41 = -008B
65 - FF01 = -01CB
66 - FEC1 = -010B
67 - FE81 = -014B
68 - FE41 = -018B select (6)
69 - FE01 = -01CB status (7)
70 - FE03 = command (7)
71 
72 - FA00 = ESP, 2 byte register spacing
73 - F9CC = data
74 
75 - F047 = -0F85 (-0FB9) interrupt request? (bit 3)
76 - F040 = -0F8C interrupt request? (bit 1) Write anything = clear irq?
77 - F000 = some status register
78 
79 - F04C = DMA address (long)
80 - F04A = number of words
81 - F044 = ???
82 - F047 = bit 7 = start dma
83 
84 */
85 
86 #define MAX_IDE_UNITS 10
87 
88 static struct ide_board *gvp_ide_rom_board, *gvp_ide_controller_board;
89 static struct ide_board *alf_board[MAX_DUPLICATE_EXPANSION_BOARDS];
90 static struct ide_board *apollo_board[MAX_DUPLICATE_EXPANSION_BOARDS];
91 static struct ide_board *masoboshi_board[MAX_DUPLICATE_EXPANSION_BOARDS];
92 static struct ide_board *adide_board[MAX_DUPLICATE_EXPANSION_BOARDS];
93 static struct ide_board *mtec_board[MAX_DUPLICATE_EXPANSION_BOARDS];
94 static struct ide_board *protar_board[MAX_DUPLICATE_EXPANSION_BOARDS];
95 static struct ide_board *rochard_board[MAX_DUPLICATE_EXPANSION_BOARDS];
96 static struct ide_board *x86_at_ide_board[MAX_DUPLICATE_EXPANSION_BOARDS];
97 static struct ide_board *golemfast_board[MAX_DUPLICATE_EXPANSION_BOARDS];
98 
99 static struct ide_hdf *idecontroller_drive[TOTAL_IDE * 2];
100 static struct ide_thread_state idecontroller_its;
101 
102 static struct ide_board *ide_boards[MAX_IDE_UNITS + 1];
103 
freencrunit(struct ide_board * ide)104 static void freencrunit(struct ide_board *ide)
105 {
106 	if (!ide)
107 		return;
108 	for (int i = 0; i < MAX_IDE_UNITS; i++) {
109 		if (ide_boards[i] == ide) {
110 			ide_boards[i] = NULL;
111 		}
112 	}
113 	for(int i = 0; i < MAX_IDE_PORTS_BOARD; i++) {
114 		remove_ide_unit(&ide->ide[i], 0);
115 	}
116 	if (ide->self_ptr)
117 		*ide->self_ptr = NULL;
118 	xfree(ide->rom);
119 	xfree(ide);
120 }
121 
allocide(struct ide_board ** idep,struct romconfig * rc,int ch)122 static struct ide_board *allocide(struct ide_board **idep, struct romconfig *rc, int ch)
123 {
124 	struct ide_board *ide;
125 
126 	if (ch < 0) {
127 		if (*idep) {
128 			freencrunit(*idep);
129 			*idep = NULL;
130 		}
131 		ide = xcalloc(struct ide_board, 1);
132 		for (int i = 0; i < MAX_IDE_UNITS; i++) {
133 			if (ide_boards[i] == NULL) {
134 				ide_boards[i] = ide;
135 				rc->unitdata = ide;
136 				ide->rc = rc;
137 				ide->self_ptr = idep;
138 				if (idep)
139 					*idep = ide;
140 				return ide;
141 			}
142 		}
143 	}
144 	return *idep;
145 }
146 
getide(struct romconfig * rc)147 static struct ide_board *getide(struct romconfig *rc)
148 {
149 	for (int i = 0; i < MAX_IDE_UNITS; i++) {
150 		if (ide_boards[i]) {
151 			struct ide_board *ide = ide_boards[i];
152 			if (ide->rc == rc) {
153 				ide->original_rc = rc;
154 				ide->rc = NULL;
155 				return ide;
156 			}
157 		}
158 	}
159 	return NULL;
160 }
161 
getideboard(uaecptr addr)162 static struct ide_board *getideboard(uaecptr addr)
163 {
164 	for (int i = 0; ide_boards[i]; i++) {
165 		if (!ide_boards[i]->baseaddress && !ide_boards[i]->configured)
166 			return ide_boards[i];
167 		if ((addr & ~ide_boards[i]->mask) == ide_boards[i]->baseaddress)
168 			return ide_boards[i];
169 	}
170 	return NULL;
171 }
172 
init_ide(struct ide_board * board,int ide_num,int maxunit,bool byteswap,bool adide)173 static void init_ide(struct ide_board *board, int ide_num, int maxunit, bool byteswap, bool adide)
174 {
175 	for (int i = 0; i < maxunit / 2; i++) {
176 		struct ide_hdf **idetable = &idecontroller_drive[(ide_num + i) * 2];
177 		alloc_ide_mem (idetable, 2, &idecontroller_its);
178 		board->ide[i] = idetable[0];
179 		idetable[0]->board = board;
180 		idetable[1]->board = board;
181 		idetable[0]->byteswap = byteswap;
182 		idetable[1]->byteswap = byteswap;
183 		idetable[0]->adide = adide;
184 		idetable[1]->adide = adide;
185 		ide_initialize(idecontroller_drive, ide_num + i);
186 	}
187 	idecontroller_its.idetable = idecontroller_drive;
188 	idecontroller_its.idetotal = TOTAL_IDE * 2;
189 	start_ide_thread(&idecontroller_its);
190 }
191 
add_ide_standard_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc,struct ide_board ** ideboard,int idetype,bool byteswap,bool adide,int maxunit)192 static void add_ide_standard_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc, struct ide_board **ideboard, int idetype, bool byteswap, bool adide, int maxunit)
193 {
194 	struct ide_hdf *ide;
195 	struct ide_board *ideb;
196 	if (ch >= maxunit)
197 		return;
198 	ideb = allocide(&ideboard[ci->controller_type_unit], rc, ch);
199 	if (!ideb)
200 		return;
201 	ideb->keepautoconfig = true;
202 	ideb->type = idetype;
203 	ide = add_ide_unit (&idecontroller_drive[(idetype + ci->controller_type_unit) * 2], 2, ch, ci, rc);
204 	init_ide(ideb, idetype + ci->controller_type_unit, maxunit, byteswap, adide);
205 }
206 
ide_interrupt_check(struct ide_board * board,bool edge_triggered)207 static bool ide_interrupt_check(struct ide_board *board, bool edge_triggered)
208 {
209 	if (!board->configured)
210 		return false;
211 	bool irq = false;
212 	for (int i = 0; i < MAX_IDE_PORTS_BOARD; i++) {
213 		if (board->ide[i] && !irq) {
214 			irq = ide_irq_check(board->ide[i], edge_triggered);
215 		}
216 	}
217 #if 0
218 	if (board->irq != irq)
219 		write_log(_T("IDE irq %d -> %d\n"), board->irq, irq);
220 #endif
221 	board->irq = irq;
222 	return irq;
223 }
224 
ide_rethink(struct ide_board * board,bool edge_triggered)225 static bool ide_rethink(struct ide_board *board, bool edge_triggered)
226 {
227 	bool irq = false;
228 	if (board->configured) {
229 		if (board->intena && ide_interrupt_check(board, edge_triggered)) {
230 			irq = true;
231 		}
232 	}
233 	return irq;
234 }
235 
236 void x86_doirq(uint8_t irqnum);
237 
idecontroller_rethink(void)238 void idecontroller_rethink(void)
239 {
240 	bool irq = false;
241 	for (int i = 0; ide_boards[i]; i++) {
242 		if (ide_boards[i] == x86_at_ide_board[0] || ide_boards[i] == x86_at_ide_board[1]) {
243 			bool x86irq = ide_rethink(ide_boards[i], true);
244 			if (x86irq) {
245 				//write_log(_T("x86 IDE IRQ\n"));
246 				x86_doirq(ide_boards[i] == x86_at_ide_board[0] ? 14 : 15);
247 			}
248 		} else {
249 			irq |= ide_rethink(ide_boards[i], false);
250 		}
251 	}
252 	if (irq && !(intreq & 0x0008)) {
253 		INTREQ_0(0x8000 | 0x0008);
254 	}
255 }
256 
idecontroller_hsync(void)257 void idecontroller_hsync(void)
258 {
259 	for (int i = 0; ide_boards[i]; i++) {
260 		struct ide_board *board = ide_boards[i];
261 		if (board->configured) {
262 			for (int j = 0; j < MAX_IDE_PORTS_BOARD; j++) {
263 				if (board->ide[j]) {
264 					ide_interrupt_hsync(board->ide[j]);
265 				}
266 			}
267 			if (ide_interrupt_check(board, false)) {
268 				idecontroller_rethink();
269 			}
270 		}
271 	}
272 }
273 
reset_ide(struct ide_board * board)274 static void reset_ide(struct ide_board *board)
275 {
276 	board->configured = 0;
277 	board->intena = false;
278 	board->enabled = false;
279 }
280 
idecontroller_reset(void)281 void idecontroller_reset(void)
282 {
283 	for (int i = 0; ide_boards[i]; i++) {
284 		reset_ide(ide_boards[i]);
285 	}
286 }
287 
idecontroller_free(void)288 void idecontroller_free(void)
289 {
290 	stop_ide_thread(&idecontroller_its);
291 	for (int i = 0; i < MAX_IDE_UNITS; i++) {
292 		freencrunit(ide_boards[i]);
293 	}
294 }
295 
is_gvp2_intreq(uaecptr addr)296 static bool is_gvp2_intreq(uaecptr addr)
297 {
298 	if (ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SII) && (addr & 0x440) == 0x440)
299 		return true;
300 	return false;
301 }
is_gvp1_intreq(uaecptr addr)302 static bool is_gvp1_intreq(uaecptr addr)
303 {
304 	if (ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SI) && (addr & 0x440) == 0x40)
305 		return true;
306 	return false;
307 }
308 
get_ide_is_8bit(struct ide_board * board)309 static bool get_ide_is_8bit(struct ide_board *board)
310 {
311 	struct ide_hdf *ide = board->ide[0];
312 	if (!ide)
313 		return false;
314 	if (ide->ide_drv)
315 		ide = ide->pair;
316 	return ide->mode_8bit;
317 }
318 
get_ide_reg_multi(struct ide_board * board,int reg,int portnum,int dataportsize)319 static uae_u32 get_ide_reg_multi(struct ide_board *board, int reg, int portnum, int dataportsize)
320 {
321 	struct ide_hdf *ide = board->ide[portnum];
322 	if (!ide)
323 		return 0;
324 	if (ide->ide_drv)
325 		ide = ide->pair;
326 	if (reg == 0) {
327 		if (dataportsize)
328 			return ide_get_data(ide);
329 		else
330 			return ide_get_data_8bit(ide);
331 	} else {
332 		return ide_read_reg(ide, reg);
333 	}
334 }
put_ide_reg_multi(struct ide_board * board,int reg,uae_u32 v,int portnum,int dataportsize)335 static void put_ide_reg_multi(struct ide_board *board, int reg, uae_u32 v, int portnum, int dataportsize)
336 {
337 	struct ide_hdf *ide = board->ide[portnum];
338 	if (!ide)
339 		return;
340 	if (ide->ide_drv)
341 		ide = ide->pair;
342 	if (reg == 0) {
343 		if (dataportsize)
344 			ide_put_data(ide, v);
345 		else
346 			ide_put_data_8bit(ide, v);
347 	} else {
348 		ide_write_reg(ide, reg, v);
349 	}
350 }
get_ide_reg(struct ide_board * board,int reg)351 static uae_u32 get_ide_reg(struct ide_board *board, int reg)
352 {
353 	return get_ide_reg_multi(board, reg, 0, 1);
354 }
put_ide_reg(struct ide_board * board,int reg,uae_u32 v)355 static void put_ide_reg(struct ide_board *board, int reg, uae_u32 v)
356 {
357 	put_ide_reg_multi(board, reg, v, 0, 1);
358 }
get_ide_reg_8bitdata(struct ide_board * board,int reg)359 static uae_u32 get_ide_reg_8bitdata(struct ide_board *board, int reg)
360 {
361 	return get_ide_reg_multi(board, reg, 0, 0);
362 }
put_ide_reg_8bitdata(struct ide_board * board,int reg,uae_u32 v)363 static void put_ide_reg_8bitdata(struct ide_board *board, int reg, uae_u32 v)
364 {
365 	put_ide_reg_multi(board, reg, v, 0, 0);
366 }
367 
368 
get_gvp_reg(uaecptr addr,struct ide_board * board)369 static int get_gvp_reg(uaecptr addr, struct ide_board *board)
370 {
371 	int reg = -1;
372 
373 	if (addr & 0x1000) {
374 		reg = IDE_SECONDARY + ((addr >> 8) & 7);
375 	} else if (addr & 0x0800) {
376 		reg = (addr >> 8) & 7;
377 	}
378 	if (!(addr & 0x400) && (addr & 0x20)) {
379 		if (reg < 0)
380 			reg = 0;
381 		int extra = (addr >> 1) & 15;
382 		if (extra >= 8)
383 			reg |= IDE_SECONDARY;
384 		reg |= extra;
385 	}
386 	if (reg >= 0)
387 		reg &= IDE_SECONDARY | 7;
388 
389 	return reg;
390 }
391 
get_apollo_reg(uaecptr addr,struct ide_board * board)392 static int get_apollo_reg(uaecptr addr, struct ide_board *board)
393 {
394 	if (addr & 0x4000)
395 		return -1;
396 	int reg = addr & 0x1fff;
397 	reg >>= 10;
398 	if (addr & 0x2000)
399 		reg |= IDE_SECONDARY;
400 	if (reg != 0 && !(addr & 1))
401 		reg = -1;
402 	return reg;
403 }
404 
get_alf_reg(uaecptr addr,struct ide_board * board)405 static int get_alf_reg(uaecptr addr, struct ide_board *board)
406 {
407 	if (addr & 0x8000)
408 		return -1;
409 	if (addr & 0x4000) {
410 		;
411 	} else if (addr & 0x1000) {
412 		addr &= 0xfff;
413 		addr >>= 9;
414 	} else if (addr & 0x2000) {
415 		addr &= 0xfff;
416 		addr >>= 9;
417 		addr |= IDE_SECONDARY;
418 	}
419 	return addr;
420 }
421 
get_masoboshi_reg(uaecptr addr,struct ide_board * board)422 static int get_masoboshi_reg(uaecptr addr, struct ide_board *board)
423 {
424 	int reg;
425 	if (addr < 0xfc00)
426 		return -1;
427 	reg = 7 - ((addr >> 6) & 7);
428 	if (addr < 0xfe00)
429 		reg |= IDE_SECONDARY;
430 	return reg;
431 }
432 
get_adide_reg(uaecptr addr,struct ide_board * board)433 static int get_adide_reg(uaecptr addr, struct ide_board *board)
434 {
435 	int reg;
436 	if (addr & 0x8000)
437 		return -1;
438 	reg = (addr >> 1) & 7;
439 	if (addr & 0x10)
440 		reg |= IDE_SECONDARY;
441 	return reg;
442 }
443 
get_rochard_reg(uaecptr addr,struct ide_board * board,int * portnum)444 static int get_rochard_reg(uaecptr addr, struct ide_board *board, int *portnum)
445 {
446 	int reg = -1;
447 	if ((addr & 0x8001) != 0x8001)
448 		return -1;
449 	*portnum = (addr & 0x4000) ? 1 : 0;
450 	reg = (addr >> 5) & 7;
451 	if (addr & 0x2000)
452 		reg |= IDE_SECONDARY;
453 	return reg;
454 }
455 
get_golemfast_reg(uaecptr addr,struct ide_board * board)456 static int get_golemfast_reg(uaecptr addr, struct ide_board *board)
457 {
458 	int reg = -1;
459 	if ((addr & 0x8001) != 0x8000)
460 		return -1;
461 	reg = (addr >> 2) & 7;
462 	if (addr & 0x2000)
463 		reg |= IDE_SECONDARY;
464 	return reg;
465 }
466 
getidenum(struct ide_board * board,struct ide_board ** arr)467 static int getidenum(struct ide_board *board, struct ide_board **arr)
468 {
469 	for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) {
470 		if (board == arr[i])
471 			return i;
472 	}
473 	return 0;
474 }
475 
ide_read_byte(struct ide_board * board,uaecptr addr)476 static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr)
477 {
478 	uaecptr oaddr = addr;
479 	uae_u8 v = 0xff;
480 
481 	addr &= board->mask;
482 
483 #if DEBUG_IDE
484 	write_log(_T("IDE IO BYTE READ %08x %08x\n"), addr, M68K_GETPC);
485 #endif
486 
487 	if (addr < 0x40 && (!board->configured || board->keepautoconfig))
488 		return board->acmemory[addr];
489 
490 	if (board->type == ALF_IDE) {
491 
492 		if (addr < 0x1100 || (addr & 1)) {
493 			if (board->rom)
494 				v = board->rom[addr & board->rom_mask];
495 			return v;
496 		}
497 		int regnum = get_alf_reg(addr, board);
498 		if (regnum >= 0) {
499 			v = get_ide_reg(board, regnum);
500 		}
501 #if DEBUG_IDE_ALF
502 		write_log(_T("ALF GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
503 #endif
504 
505 	} else if (board->type == GOLEMFAST_IDE) {
506 
507 		if (!(addr & 0x8000)) {
508 			if (board->rom) {
509 				v = board->rom[addr & board->rom_mask];
510 			}
511 		} else if ((addr & 0x8700) == 0x8400 || (addr & 0x8700) == 0x8000) {
512 			v = golemfast_ncr9x_scsi_get(oaddr, getidenum(board, golemfast_board));
513 		} else if ((addr & 0x8700) == 0x8100) {
514 			int regnum = get_golemfast_reg(addr, board);
515 			if (regnum >= 0) {
516 				v = get_ide_reg(board, regnum);
517 			}
518 		} else if ((addr & 0x8700) == 0x8300) {
519 			v = board->original_rc->device_id ^ 7;
520 			if (!board->original_rc->autoboot_disabled)
521 				v |= 0x20;
522 			if (!(board->original_rc->device_settings & 1))
523 				v |= 0x08;
524 			if (ide_irq_check(board->ide[0], false) || ide_drq_check(board->ide[0]))
525 				v |= 0x80; // IDE IRQ | DRQ
526 			//write_log(_T("READ JUMPER %08x %02x %08x\n"), addr, v, M68K_GETPC);
527 		}
528 
529 	} else if (board->type == MASOBOSHI_IDE) {
530 		int regnum = -1;
531 		bool rom = false;
532 		if (addr >= MASOBOSHI_ROM_OFFSET && addr < MASOBOSHI_ROM_OFFSET_END) {
533 			if (board->rom) {
534 				v = board->rom[addr & board->rom_mask];
535 				rom = true;
536 			}
537 		} else if (addr >= 0xf000 && addr <= 0xf007) {
538 			if (board->subtype)
539 				v = masoboshi_ncr9x_scsi_get(oaddr, getidenum(board, masoboshi_board));
540 		} else if (addr == 0xf040) {
541 			v = 1;
542 			if (ide_irq_check(board->ide[0], false)) {
543 				v |= 2;
544 				board->irq = true;
545 			}
546 			if (board->irq) {
547 				v &= ~1;
548 			}
549 			v |= masoboshi_ncr9x_scsi_get(oaddr, getidenum(board, masoboshi_board));
550 		} else if (addr == 0xf047) {
551 			v = board->state;
552 		} else {
553 			regnum = get_masoboshi_reg(addr, board);
554 			if (regnum >= 0) {
555 				v = get_ide_reg(board, regnum);
556 			} else if (addr >= MASOBOSHI_SCSI_OFFSET && addr < MASOBOSHI_SCSI_OFFSET_END) {
557 				if (board->subtype)
558 					v = masoboshi_ncr9x_scsi_get(oaddr, getidenum(board, masoboshi_board));
559 				else
560 					v = 0xff;
561 			}
562 		}
563 #if DEBUG_IDE_MASOBOSHI
564 		if (!rom)
565 			write_log(_T("MASOBOSHI BYTE GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
566 #endif
567 	} else if (board->type == APOLLO_IDE) {
568 
569 		if (addr >= APOLLO_ROM_OFFSET) {
570 			if (board->rom)
571 				v = board->rom[(addr - APOLLO_ROM_OFFSET) & board->rom_mask];
572 		} else if (board->configured) {
573 			if ((addr & 0xc000) == 0x4000) {
574 				v = apollo_scsi_bget(oaddr);
575 			} else if (addr < 0x4000) {
576 				int regnum = get_apollo_reg(addr, board);
577 				if (regnum >= 0) {
578 					v = get_ide_reg(board, regnum);
579 				} else {
580 					v = 0;
581 				}
582 			}
583 		}
584 
585 	} else if (board->type == GVP_IDE) {
586 
587 		if (addr >= GVP_IDE_ROM_OFFSET) {
588 			if (board->rom) {
589 				if (addr & 1)
590 					v = 0xe8; // board id
591 				else
592 					v = board->rom[((addr - GVP_IDE_ROM_OFFSET) / 2) & board->rom_mask];
593 				return v;
594 			}
595 			v = 0xe8;
596 #if DEBUG_IDE_GVP
597 			write_log(_T("GVP BOOT GET %08x %02x %08x\n"), addr, v, M68K_GETPC);
598 #endif
599 			return v;
600 		}
601 		if (board->configured) {
602 			if (board == gvp_ide_rom_board && ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SII)) {
603 				if (addr == 0x42) {
604 					v = 0xff;
605 				}
606 #if DEBUG_IDE_GVP
607 				write_log(_T("GVP BOOT GET %08x %02x %08x\n"), addr, v, M68K_GETPC);
608 #endif
609 			} else {
610 				int regnum = get_gvp_reg(addr, board);
611 #if DEBUG_IDE_GVP
612 				write_log(_T("GVP IDE GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
613 #endif
614 				if (regnum >= 0) {
615 					v = get_ide_reg(board, regnum);
616 				} else if (is_gvp2_intreq(addr)) {
617 					v = board->irq ? 0x40 : 0x00;
618 #if DEBUG_IDE_GVP
619 					write_log(_T("GVP IRQ %02x\n"), v);
620 #endif
621 					ide_interrupt_check(board, false);
622 				} else if (is_gvp1_intreq(addr)) {
623 					v = board->irq ? 0x80 : 0x00;
624 #if DEBUG_IDE_GVP
625 					write_log(_T("GVP IRQ %02x\n"), v);
626 #endif
627 					ide_interrupt_check(board, false);
628 				}
629 			}
630 		} else {
631 			v = 0xff;
632 		}
633 
634 	} else if (board->type == ADIDE_IDE) {
635 
636 		if (addr & ADIDE_ROM_OFFSET) {
637 			v = board->rom[addr & board->rom_mask];
638 		} else if (board->configured) {
639 			int regnum = get_adide_reg(addr, board);
640 			v = get_ide_reg(board, regnum);
641 			v = adide_decode_word(v);
642 		}
643 
644 	} else if (board->type == MTEC_IDE) {
645 
646 		if (!(addr & 0x8000)) {
647 			v = board->rom[addr & board->rom_mask];
648 		} else if (board->configured) {
649 			v = get_ide_reg(board, (addr >> 8) & 7);
650 		}
651 
652 	} else if (board->type == PROTAR_IDE) {
653 
654 		v = board->rom[addr & board->rom_mask];
655 
656 	} else if (board->type == ROCHARD_IDE) {
657 
658 		if (addr & 0x8000) {
659 			int portnum;
660 			int regnum = get_rochard_reg(addr, board, &portnum);
661 			if (regnum >= 0 && board->ide[portnum])
662 				v = get_ide_reg_multi(board, regnum, portnum, 1);
663 		} else if ((addr & 0x7c00) == 0x7000) {
664 			if (board->subtype)
665 				v = rochard_scsi_get(oaddr);
666 			else
667 				v = 0;
668 		} else {
669 			v = board->rom[addr & board->rom_mask];
670 		}
671 
672 
673 	}
674 
675 	return v;
676 }
677 
ide_read_word(struct ide_board * board,uaecptr addr)678 static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr)
679 {
680 	uae_u32 v = 0xffff;
681 
682 	addr &= board->mask;
683 
684 	if (addr < 0x40 && (!board->configured || board->keepautoconfig)) {
685 		v = board->acmemory[addr] << 8;
686 		v |= board->acmemory[addr + 1];
687 		return v;
688 	}
689 
690 	if (board->type == APOLLO_IDE) {
691 
692 		if (addr >= APOLLO_ROM_OFFSET) {
693 			if (board->rom) {
694 				v = board->rom[(addr + 0 - APOLLO_ROM_OFFSET) & board->rom_mask];
695 				v <<= 8;
696 				v |= board->rom[(addr + 1 - APOLLO_ROM_OFFSET) & board->rom_mask];
697 			}
698 		}
699 
700 	} else if (board->type == ROCHARD_IDE) {
701 
702 		if (addr < 8192) {
703 			if (board->rom) {
704 				v = board->rom[(addr + 0) & board->rom_mask];
705 				v <<= 8;
706 				v |= board->rom[(addr + 1) & board->rom_mask];
707 			}
708 		}
709 
710 	}
711 
712 	if (board->configured) {
713 
714 		if (board->type == ALF_IDE) {
715 
716 			int regnum = get_alf_reg(addr, board);
717 			if (regnum == IDE_DATA) {
718 				v = get_ide_reg(board, IDE_DATA);
719 			} else {
720 				v = 0;
721 				if (addr == 0x4000 && board->intena)
722 					v = board->irq ? 0x8000 : 0x0000;
723 #if DEBUG_IDE_ALF
724 				write_log(_T("ALF IO WORD READ %08x %08x\n"), addr, M68K_GETPC);
725 #endif
726 			}
727 
728 		} else if (board->type == GOLEMFAST_IDE) {
729 
730 			if ((addr & 0x8700) == 0x8100) {
731 				int regnum = get_golemfast_reg(addr, board);
732 				if (regnum == IDE_DATA) {
733 					v = get_ide_reg(board, IDE_DATA);
734 				} else {
735 					v = ide_read_byte(board, addr) << 8;
736 					v |= ide_read_byte(board, addr + 1);
737 				}
738 			} else {
739 				v = ide_read_byte(board, addr) << 8;
740 				v |= ide_read_byte(board, addr + 1);
741 			}
742 
743 		} else if (board->type == MASOBOSHI_IDE) {
744 
745 			if (addr >= MASOBOSHI_ROM_OFFSET && addr < MASOBOSHI_ROM_OFFSET_END) {
746 				if (board->rom) {
747 					v = board->rom[addr & board->rom_mask] << 8;
748 					v |= board->rom[(addr + 1) & board->rom_mask];
749 				}
750 			} else {
751 				int regnum = get_masoboshi_reg(addr, board);
752 				if (regnum == IDE_DATA) {
753 					v = get_ide_reg(board, IDE_DATA);
754 				} else {
755 					v = ide_read_byte(board, addr) << 8;
756 					v |= ide_read_byte(board, addr + 1);
757 				}
758 			}
759 
760 		} else if (board->type == APOLLO_IDE) {
761 
762 			if ((addr & 0xc000) == 0x4000) {
763 				v = apollo_scsi_bget(addr);
764 				v <<= 8;
765 				v |= apollo_scsi_bget(addr + 1);
766 			} else if (addr < 0x4000) {
767 				int regnum = get_apollo_reg(addr, board);
768 				if (regnum == IDE_DATA) {
769 					v = get_ide_reg(board, IDE_DATA);
770 				} else {
771 					v = 0;
772 				}
773 			}
774 
775 		} else if (board->type == GVP_IDE) {
776 
777 			if (board == gvp_ide_controller_board || ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SI)) {
778 				if (addr < 0x60) {
779 					if (is_gvp1_intreq(addr))
780 						v = gvp_ide_controller_board->irq ? 0x8000 : 0x0000;
781 					else if (addr == 0x40) {
782 						if (ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SII))
783 							v = board->intena ? 8 : 0;
784 					}
785 #if DEBUG_IDE_GVP
786 					write_log(_T("GVP IO WORD READ %08x %08x\n"), addr, M68K_GETPC);
787 #endif
788 				} else {
789 					int regnum = get_gvp_reg(addr, board);
790 					if (regnum == IDE_DATA) {
791 						v = get_ide_reg(board, IDE_DATA);
792 #if DEBUG_IDE_GVP > 2
793 						write_log(_T("IDE WORD READ %04x\n"), v);
794 #endif
795 					} else {
796 						v = ide_read_byte(board, addr) << 8;
797 						v |= ide_read_byte(board, addr + 1);
798 					}
799 				}
800 			}
801 
802 		} else if (board->type == ADIDE_IDE) {
803 
804 			int regnum = get_adide_reg(addr, board);
805 			if (regnum == IDE_DATA) {
806 				v = get_ide_reg(board, IDE_DATA);
807 			} else {
808 				v = get_ide_reg(board, regnum) << 8;
809 				v = adide_decode_word(v);
810 			}
811 
812 		} else if (board->type == MTEC_IDE) {
813 
814 			if (board->configured && (addr & 0x8000)) {
815 				int regnum = (addr >> 8) & 7;
816 				if (regnum == IDE_DATA)
817 					v = get_ide_reg(board, regnum);
818 				else
819 					v = ide_read_byte(board, addr) << 8;
820 			}
821 
822 		} else if (board->type == ROCHARD_IDE) {
823 
824 			if (board->configured && (addr & 0x8020) == 0x8000) {
825 				v = get_ide_reg_multi(board, IDE_DATA, (addr & 0x4000) ? 1 : 0, 1);
826 			}
827 
828 		}
829 
830 	}
831 
832 #if DEBUG_IDE
833 	write_log(_T("IDE IO WORD READ %08x %04x %08x\n"), addr, v, M68K_GETPC);
834 #endif
835 
836 	return v;
837 }
838 
ide_write_byte(struct ide_board * board,uaecptr addr,uae_u8 v)839 static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v)
840 {
841 	uaecptr oaddr = addr;
842 	addr &= board->mask;
843 
844 #if DEBUG_IDE
845 	write_log(_T("IDE IO BYTE WRITE %08x=%02x %08x\n"), addr, v, M68K_GETPC);
846 #endif
847 
848 	if (!board->configured) {
849 		addrbank *ab = board->bank;
850 		if (addr == 0x48) {
851 			map_banks_z2(ab, v, (board->mask + 1) >> 16);
852 			board->baseaddress = v << 16;
853 			board->configured = 1;
854 			if (board->type == ROCHARD_IDE) {
855 				rochard_scsi_init(board->original_rc, board->baseaddress);
856 			} else if (board->type == MASOBOSHI_IDE) {
857 				ncr_masoboshi_autoconfig_init(board->original_rc, board->baseaddress);
858 			} else if (board->type == GOLEMFAST_IDE) {
859 				ncr_golemfast_autoconfig_init(board->original_rc, board->baseaddress);
860 			}
861 			expamem_next(ab, NULL);
862 			return;
863 		}
864 		if (addr == 0x4c) {
865 			board->configured = 1;
866 			expamem_shutup(ab);
867 			return;
868 		}
869 	}
870 	if (board->configured) {
871 		if (board->type == ALF_IDE) {
872 			int regnum = get_alf_reg(addr, board);
873 			if (regnum >= 0)
874 				put_ide_reg(board, regnum, v);
875 #if DEBUG_IDE_ALF
876 			write_log(_T("ALF PUT %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
877 #endif
878 		} else if (board->type == GOLEMFAST_IDE) {
879 
880 			if ((addr & 0x8700) == 0x8400 || (addr & 0x8700) == 0x8000) {
881 				golemfast_ncr9x_scsi_put(oaddr, v, getidenum(board, golemfast_board));
882 			} else if ((addr & 0x8700) == 0x8100) {
883 				int regnum = get_golemfast_reg(addr, board);
884 				if (regnum >= 0)
885 					put_ide_reg(board, regnum, v);
886 			}
887 
888 		} else if (board->type == MASOBOSHI_IDE) {
889 
890 #if DEBUG_IDE_MASOBOSHI
891 			write_log(_T("MASOBOSHI IO BYTE PUT %08x %02x %08x\n"), addr, v, M68K_GETPC);
892 #endif
893 			int regnum = get_masoboshi_reg(addr, board);
894 			if (regnum >= 0) {
895 				put_ide_reg(board, regnum, v);
896 			} else if (addr >= MASOBOSHI_SCSI_OFFSET && addr < MASOBOSHI_SCSI_OFFSET_END) {
897 				if (board->subtype)
898 					masoboshi_ncr9x_scsi_put(oaddr, v, getidenum(board, masoboshi_board));
899 			} else if ((addr >= 0xf000 && addr <= 0xf007)) {
900 				if (board->subtype)
901 					masoboshi_ncr9x_scsi_put(oaddr, v, getidenum(board, masoboshi_board));
902 			} else if (addr >= 0xf04a && addr <= 0xf04f) {
903 				// dma controller
904 				masoboshi_ncr9x_scsi_put(oaddr, v, getidenum(board, masoboshi_board));
905 			} else if (addr >= 0xf040 && addr < 0xf048) {
906 				masoboshi_ncr9x_scsi_put(oaddr, v, getidenum(board, masoboshi_board));
907 				if (addr == 0xf047) {
908 					board->state = v;
909 					board->intena = (v & 8) != 0;
910 				}
911 				if (addr == 0xf040) {
912 					board->irq = false;
913 				}
914 				write_log(_T("MASOBOSHI STATUS BYTE PUT %08x %02x %08x\n"), addr, v, M68K_GETPC);
915 			}
916 
917 		} else if (board->type == APOLLO_IDE) {
918 
919 			if ((addr & 0xc000) == 0x4000) {
920 				apollo_scsi_bput(oaddr, v);
921 			} else if (addr < 0x4000) {
922 				int regnum = get_apollo_reg(addr, board);
923 				if (regnum >= 0) {
924 					put_ide_reg(board, regnum, v);
925 				}
926 			}
927 
928 		} else if (board->type == GVP_IDE) {
929 
930 			if (board == gvp_ide_rom_board && ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SII)) {
931 #if DEBUG_IDE_GVP
932 				write_log(_T("GVP BOOT PUT %08x %02x %08x\n"), addr, v, M68K_GETPC);
933 #endif
934 			} else {
935 				int regnum = get_gvp_reg(addr, board);
936 #if DEBUG_IDE_GVP
937 				write_log(_T("GVP IDE PUT %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
938 #endif
939 				if (regnum >= 0)
940 					put_ide_reg(board, regnum, v);
941 			}
942 
943 		} else if (board->type == ADIDE_IDE) {
944 
945 			if (board->configured) {
946 				int regnum = get_adide_reg(addr, board);
947 				v = adide_encode_word(v);
948 				put_ide_reg(board, regnum, v);
949 			}
950 
951 		} else if (board->type == MTEC_IDE) {
952 
953 			if (board->configured && (addr & 0x8000)) {
954 				put_ide_reg(board, (addr >> 8) & 7, v);
955 			}
956 
957 		} else if (board->type == ROCHARD_IDE) {
958 
959 			if (board->configured) {
960 				if (addr & 0x8000) {
961 					int portnum;
962 					int regnum = get_rochard_reg(addr, board, &portnum);
963 					if (regnum >= 0 && board->ide[portnum])
964 						put_ide_reg_multi(board, regnum, v, portnum, 1);
965 				} else if ((addr & 0x7c00) == 0x7000) {
966 					if (board->subtype)
967 						rochard_scsi_put(oaddr, v);
968 				}
969 			}
970 		}
971 
972 	}
973 }
974 
ide_write_word(struct ide_board * board,uaecptr addr,uae_u16 v)975 static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v)
976 {
977 	addr &= board->mask;
978 
979 #if DEBUG_IDE
980 	write_log(_T("IDE IO WORD WRITE %08x=%04x %08x\n"), addr, v, M68K_GETPC);
981 #endif
982 	if (board->configured) {
983 		if (board->type == ALF_IDE) {
984 
985 			int regnum = get_alf_reg(addr, board);
986 			if (regnum == IDE_DATA) {
987 				put_ide_reg(board, IDE_DATA, v);
988 			} else {
989 #if DEBUG_IDE_ALF
990 				write_log(_T("ALF IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC);
991 #endif
992 			}
993 
994 
995 		} else if (board->type == GOLEMFAST_IDE) {
996 
997 			if ((addr & 0x8700) == 0x8100) {
998 				int regnum = get_golemfast_reg(addr, board);
999 				if (regnum == IDE_DATA) {
1000 					put_ide_reg(board, IDE_DATA, v);
1001 				} else {
1002 					ide_write_byte(board, addr, v >> 8);
1003 					ide_write_byte(board, addr + 1, v);
1004 				}
1005 			} else {
1006 				ide_write_byte(board, addr, v >> 8);
1007 				ide_write_byte(board, addr + 1, v);
1008 			}
1009 
1010 		} else if (board->type == MASOBOSHI_IDE) {
1011 
1012 			int regnum = get_masoboshi_reg(addr, board);
1013 			if (regnum == IDE_DATA) {
1014 				put_ide_reg(board, IDE_DATA, v);
1015 			} else {
1016 				ide_write_byte(board, addr, v >> 8);
1017 				ide_write_byte(board, addr + 1, v);
1018 			}
1019 #if DEBUG_IDE_MASOBOSHI
1020 			write_log(_T("MASOBOSHI IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC);
1021 #endif
1022 
1023 		} else if (board->type == APOLLO_IDE) {
1024 
1025 			if ((addr & 0xc000) == 0x4000) {
1026 				apollo_scsi_bput(addr, v >> 8);
1027 				apollo_scsi_bput(addr + 1, v);
1028 			} else if (addr < 0x4000) {
1029 				int regnum = get_apollo_reg(addr, board);
1030 				if (regnum == IDE_DATA) {
1031 					put_ide_reg(board, IDE_DATA, v);
1032 				}
1033 			}
1034 
1035 		} else if (board->type == GVP_IDE) {
1036 
1037 			if (board == gvp_ide_controller_board || ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SI)) {
1038 				if (addr < 0x60) {
1039 #if DEBUG_IDE_GVP
1040 					write_log(_T("GVP IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC);
1041 #endif
1042 					if (addr == 0x40 && ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SII))
1043 						board->intena = (v & 8) != 0;
1044 				} else {
1045 					int regnum = get_gvp_reg(addr, board);
1046 					if (regnum == IDE_DATA) {
1047 						put_ide_reg(board, IDE_DATA, v);
1048 #if DEBUG_IDE_GVP > 2
1049 						write_log(_T("IDE WORD WRITE %04x\n"), v);
1050 #endif
1051 					} else {
1052 						ide_write_byte(board, addr, v >> 8);
1053 						ide_write_byte(board, addr + 1, v & 0xff);
1054 					}
1055 				}
1056 			}
1057 
1058 		} else if (board->type == ADIDE_IDE) {
1059 
1060 			int regnum = get_adide_reg(addr, board);
1061 			if (regnum == IDE_DATA) {
1062 				put_ide_reg(board, IDE_DATA, v);
1063 			} else {
1064 				v = adide_encode_word(v);
1065 				put_ide_reg(board, regnum, v >> 8);
1066 			}
1067 
1068 		} else if (board->type == MTEC_IDE) {
1069 
1070 			if (board->configured && (addr & 0x8000)) {
1071 				int regnum = (addr >> 8) & 7;
1072 				if (regnum == IDE_DATA)
1073 					put_ide_reg(board, regnum, v);
1074 				else
1075 					ide_write_byte(board, addr, v >> 8);
1076 			}
1077 
1078 		} else if (board->type == ROCHARD_IDE) {
1079 
1080 			if (board->configured && (addr & 0x8020) == 0x8000) {
1081 				put_ide_reg_multi(board, IDE_DATA, v, (addr & 0x4000) ? 1 : 0, 1);
1082 			}
1083 
1084 		}
1085 	}
1086 }
1087 
ide_read_wordi(struct ide_board * board,uaecptr addr)1088 static uae_u32 ide_read_wordi(struct ide_board *board, uaecptr addr)
1089 {
1090 	uae_u16 v = 0;
1091 	if (board->type == GOLEMFAST_IDE) {
1092 
1093 		if (!(addr & 0x8000)) {
1094 			if (board->rom) {
1095 				v = board->rom[addr & board->rom_mask] << 8;
1096 				v |= board->rom[(addr + 1) & board->rom_mask];
1097 			}
1098 		}
1099 
1100 	} else {
1101 
1102 		v = dummy_wgeti(addr);
1103 
1104 	}
1105 	return v;
1106 }
1107 
1108 
1109 
1110 IDE_MEMORY_FUNCTIONS(ide_controller_gvp, ide, gvp_ide_controller_board);
1111 
1112 addrbank gvp_ide_controller_bank = {
1113 	ide_controller_gvp_lget, ide_controller_gvp_wget, ide_controller_gvp_bget,
1114 	ide_controller_gvp_lput, ide_controller_gvp_wput, ide_controller_gvp_bput,
1115 	default_xlate, default_check, NULL, NULL, _T("GVP IDE"),
1116 	dummy_lgeti, dummy_wgeti,
1117 	ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
1118 };
1119 
1120 IDE_MEMORY_FUNCTIONS(ide_rom_gvp, ide, gvp_ide_rom_board);
1121 
1122 addrbank gvp_ide_rom_bank = {
1123 	ide_rom_gvp_lget, ide_rom_gvp_wget, ide_rom_gvp_bget,
1124 	ide_rom_gvp_lput, ide_rom_gvp_wput, ide_rom_gvp_bput,
1125 	default_xlate, default_check, NULL, NULL, _T("GVP BOOT"),
1126 	dummy_lgeti, dummy_wgeti,
1127 	ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
1128 };
1129 
ide_generic_bput(uaecptr addr,uae_u32 b)1130 static void REGPARAM2 ide_generic_bput (uaecptr addr, uae_u32 b)
1131 {
1132 	struct ide_board *ide = getideboard(addr);
1133 	if (ide)
1134 		ide_write_byte(ide, addr, b);
1135 }
ide_generic_wput(uaecptr addr,uae_u32 b)1136 static void REGPARAM2 ide_generic_wput (uaecptr addr, uae_u32 b)
1137 {
1138 	struct ide_board *ide = getideboard(addr);
1139 	if (ide)
1140 		ide_write_word(ide, addr, b);
1141 }
ide_generic_lput(uaecptr addr,uae_u32 b)1142 static void REGPARAM2 ide_generic_lput (uaecptr addr, uae_u32 b)
1143 {
1144 	struct ide_board *ide = getideboard(addr);
1145 	if (ide) {
1146 		ide_write_word(ide, addr, b >> 16);
1147 		ide_write_word(ide, addr + 2, b);
1148 	}
1149 }
ide_generic_bget(uaecptr addr)1150 static uae_u32 REGPARAM2 ide_generic_bget (uaecptr addr)
1151 {
1152 	struct ide_board *ide = getideboard(addr);
1153 	if (ide)
1154 		return ide_read_byte(ide, addr);
1155 	return 0;
1156 }
ide_generic_wget(uaecptr addr)1157 static uae_u32 REGPARAM2 ide_generic_wget (uaecptr addr)
1158 {
1159 	struct ide_board *ide = getideboard(addr);
1160 	if (ide)
1161 		return ide_read_word(ide, addr);
1162 	return 0;
1163 }
ide_generic_lget(uaecptr addr)1164 static uae_u32 REGPARAM2 ide_generic_lget (uaecptr addr)
1165 {
1166 	struct ide_board *ide = getideboard(addr);
1167 	if (ide) {
1168 		uae_u32 v = ide_read_word(ide, addr) << 16;
1169 		v |= ide_read_word(ide, addr + 2);
1170 		return v;
1171 	}
1172 	return 0;
1173 }
ide_generic_wgeti(uaecptr addr)1174 static uae_u32 REGPARAM2 ide_generic_wgeti(uaecptr addr)
1175 {
1176 	struct ide_board *ide = getideboard(addr);
1177 	if (ide)
1178 		return ide_read_wordi(ide, addr);
1179 	return 0;
1180 }
ide_generic_lgeti(uaecptr addr)1181 static uae_u32 REGPARAM2 ide_generic_lgeti(uaecptr addr)
1182 {
1183 	struct ide_board *ide = getideboard(addr);
1184 	if (ide) {
1185 		uae_u32 v = ide_read_wordi(ide, addr) << 16;
1186 		v |= ide_read_wordi(ide, addr + 2);
1187 		return v;
1188 	}
1189 	return 0;
1190 }
ide_generic_xlate(uaecptr addr)1191 static uae_u8 *REGPARAM2 ide_generic_xlate(uaecptr addr)
1192 {
1193 	struct ide_board *ide = getideboard(addr);
1194 	if (!ide)
1195 		return NULL;
1196 	addr &= ide->rom_mask;
1197 	return ide->rom + addr;
1198 
1199 }
ide_generic_check(uaecptr a,uae_u32 b)1200 static int REGPARAM2 ide_generic_check(uaecptr a, uae_u32 b)
1201 {
1202 	struct ide_board *ide = getideboard(a);
1203 	if (!ide)
1204 		return 0;
1205 	a &= ide->rom_mask;
1206 	if (a >= ide->rom_start && a + b < ide->rom_size)
1207 		return 1;
1208 	return 0;
1209 }
1210 
1211 static addrbank ide_bank_generic = {
1212 	ide_generic_lget, ide_generic_wget, ide_generic_bget,
1213 	ide_generic_lput, ide_generic_wput, ide_generic_bput,
1214 	ide_generic_xlate, ide_generic_check, NULL, NULL, _T("IDE"),
1215 	ide_generic_lgeti, ide_generic_wgeti,
1216 	ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
1217 };
1218 
1219 
ew(struct ide_board * ide,int addr,uae_u32 value)1220 static void ew(struct ide_board *ide, int addr, uae_u32 value)
1221 {
1222 	addr &= 0xffff;
1223 	if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
1224 		ide->acmemory[addr] = (value & 0xf0);
1225 		ide->acmemory[addr + 2] = (value & 0x0f) << 4;
1226 	} else {
1227 		ide->acmemory[addr] = ~(value & 0xf0);
1228 		ide->acmemory[addr + 2] = ~((value & 0x0f) << 4);
1229 	}
1230 }
1231 
1232 static const uae_u8 gvp_ide2_rom_autoconfig[16] = { 0xd1, 0x0d, 0x00, 0x00, 0x07, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 };
1233 static const uae_u8 gvp_ide2_controller_autoconfig[16] = { 0xc1, 0x0b, 0x00, 0x00, 0x07, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1234 static const uae_u8 gvp_ide1_controller_autoconfig[16] = { 0xd1, 0x08, 0x00, 0x00, 0x07, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 };
1235 
gvp_ide_rom_autoconfig_init(struct romconfig * rc)1236 addrbank *gvp_ide_rom_autoconfig_init(struct romconfig *rc)
1237 {
1238 	struct ide_board *ide = getide(rc);
1239 	const uae_u8 *autoconfig;
1240 
1241 	if (ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SI)) {
1242 		ide->bank = &gvp_ide_rom_bank;
1243 		autoconfig = gvp_ide1_controller_autoconfig;
1244 		init_ide(ide, GVP_IDE, 2, true, false);
1245 		ide->rom_size = 8192;
1246 		gvp_ide_controller_board->intena = true;
1247 		ide->intena = true;
1248 		gvp_ide_controller_board->configured = -1;
1249 	} else {
1250 		ide->bank = &gvp_ide_rom_bank;
1251 		autoconfig = gvp_ide2_rom_autoconfig;
1252 		ide->rom_size = 16384;
1253 	}
1254 	ide->configured = 0;
1255 	ide->mask = 65536 - 1;
1256 	ide->type = GVP_IDE;
1257 	ide->configured = 0;
1258 	memset(ide->acmemory, 0xff, sizeof ide->acmemory);
1259 
1260 	ide->rom = xcalloc(uae_u8, ide->rom_size);
1261 	memset(ide->rom, 0xff, ide->rom_size);
1262 	ide->rom_mask = ide->rom_size - 1;
1263 
1264 	load_rom_rc(rc, ROMTYPE_CB_A3001S1, ide->rom_size, 0, ide->rom, ide->rom_size, LOADROM_FILL);
1265 	for (int i = 0; i < 16; i++) {
1266 		uae_u8 b = autoconfig[i];
1267 		ew(ide, i * 4, b);
1268 	}
1269 	return ide->bank;
1270 }
1271 
gvp_ide_controller_autoconfig_init(struct romconfig * rc)1272 addrbank *gvp_ide_controller_autoconfig_init(struct romconfig *rc)
1273 {
1274 	struct ide_board *ide = getide(rc);
1275 
1276 	init_ide(ide, GVP_IDE, 2, true, false);
1277 	ide->configured = 0;
1278 	ide->bank = &gvp_ide_controller_bank;
1279 	memset(ide->acmemory, 0xff, sizeof ide->acmemory);
1280 	for (int i = 0; i < 16; i++) {
1281 		uae_u8 b = gvp_ide2_controller_autoconfig[i];
1282 		ew(ide, i * 4, b);
1283 	}
1284 	return ide->bank;
1285 }
1286 
gvp_add_ide_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1287 void gvp_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1288 {
1289 	struct ide_hdf *ide;
1290 
1291 	if (!allocide(&gvp_ide_rom_board, rc, ch))
1292 		return;
1293 	if (!allocide(&gvp_ide_controller_board, rc, ch))
1294 		return;
1295 	ide = add_ide_unit (&idecontroller_drive[(GVP_IDE + ci->controller_type_unit) * 2], 2, ch, ci, rc);
1296 }
1297 
1298 static const uae_u8 alf_autoconfig[16] = { 0xd1, 6, 0x00, 0x00, 0x08, 0x2c, 0x00, 0x00, 0x00, 0x00, ALF_ROM_OFFSET >> 8, ALF_ROM_OFFSET & 0xff };
1299 static const uae_u8 alfplus_autoconfig[16] = { 0xd1, 38, 0x00, 0x00, 0x08, 0x2c, 0x00, 0x00, 0x00, 0x00, ALF_ROM_OFFSET >> 8, ALF_ROM_OFFSET & 0xff };
1300 
alf_init(struct romconfig * rc)1301 addrbank *alf_init(struct romconfig *rc)
1302 {
1303 	struct ide_board *ide = getide(rc);
1304 	bool alfplus = cfgfile_board_enabled(&currprefs, ROMTYPE_ALFAPLUS, 0);
1305 
1306 	if (!ide)
1307 		return &expamem_null;
1308 
1309 	ide->configured = 0;
1310 
1311 	ide->configured = 0;
1312 	ide->bank = &ide_bank_generic;
1313 	ide->type = ALF_IDE;
1314 	ide->rom_size = 32768 * 6;
1315 	ide->userdata = alfplus;
1316 	ide->intena = alfplus;
1317 	ide->mask = 65536 - 1;
1318 
1319 	memset(ide->acmemory, 0xff, sizeof ide->acmemory);
1320 
1321 	ide->rom = xcalloc(uae_u8, ide->rom_size);
1322 	memset(ide->rom, 0xff, ide->rom_size);
1323 	ide->rom_mask = ide->rom_size - 1;
1324 
1325 	for (int i = 0; i < 16; i++) {
1326 		uae_u8 b = alfplus ? alfplus_autoconfig[i] : alf_autoconfig[i];
1327 		ew(ide, i * 4, b);
1328 	}
1329 
1330 	if (!rc->autoboot_disabled) {
1331 		struct zfile *z = read_device_from_romconfig(rc, alfplus ? ROMTYPE_ALFAPLUS : ROMTYPE_ALFA);
1332 		if (z) {
1333 			for (int i = 0; i < 0x1000 / 2; i++) {
1334 				uae_u8 b;
1335 				zfile_fread(&b, 1, 1, z);
1336 				ide->rom[ALF_ROM_OFFSET + i * 4 + 0] = b;
1337 				zfile_fread(&b, 1, 1, z);
1338 				ide->rom[ALF_ROM_OFFSET + i * 4 + 2] = b;
1339 			}
1340 			for (int i = 0; i < 32768 - 0x1000; i++) {
1341 				uae_u8 b;
1342 				zfile_fread(&b, 1, 1, z);
1343 				ide->rom[0x2000 + i * 4 + 1] = b;
1344 				zfile_fread(&b, 1, 1, z);
1345 				ide->rom[0x2000 + i * 4 + 3] = b;
1346 			}
1347 			zfile_fclose(z);
1348 		}
1349 	}
1350 	return ide->bank;
1351 }
1352 
alf_add_ide_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1353 void alf_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1354 {
1355 	add_ide_standard_unit(ch, ci, rc, alf_board, ALF_IDE, false, false, 2);
1356 }
1357 
1358 // prod 0x22 = IDE + SCSI
1359 // prod 0x23 = SCSI only
1360 // prod 0x33 = IDE only
1361 
1362 const uae_u8 apollo_autoconfig[16] = { 0xd1, 0x22, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, APOLLO_ROM_OFFSET >> 8, APOLLO_ROM_OFFSET & 0xff };
1363 const uae_u8 apollo_autoconfig_cpuboard[16] = { 0xd2, 0x23, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, APOLLO_ROM_OFFSET >> 8, APOLLO_ROM_OFFSET & 0xff };
1364 const uae_u8 apollo_autoconfig_cpuboard_060[16] = { 0xd2, 0x23, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x02, APOLLO_ROM_OFFSET >> 8, APOLLO_ROM_OFFSET & 0xff };
1365 
apollo_init(struct romconfig * rc,bool cpuboard)1366 static addrbank *apollo_init(struct romconfig *rc, bool cpuboard)
1367 {
1368 	struct ide_board *ide = getide(rc);
1369 	const uae_u8 *autoconfig;
1370 
1371 	if (!ide)
1372 		return &expamem_null;
1373 
1374 	ide->configured = 0;
1375 	ide->bank = &ide_bank_generic;
1376 	ide->rom_size = 32768;
1377 	ide->type = APOLLO_IDE;
1378 
1379 	memset(ide->acmemory, 0xff, sizeof ide->acmemory);
1380 
1381 	ide->rom = xcalloc(uae_u8, ide->rom_size);
1382 	memset(ide->rom, 0xff, ide->rom_size);
1383 	ide->rom_mask = ide->rom_size - 1;
1384 	ide->keepautoconfig = false;
1385 	autoconfig = apollo_autoconfig;
1386 	if (cpuboard) {
1387 		if (currprefs.cpu_model == 68060)
1388 			autoconfig = apollo_autoconfig_cpuboard_060;
1389 		else
1390 			autoconfig = apollo_autoconfig_cpuboard;
1391 	}
1392 	for (int i = 0; i < 16; i++) {
1393 		uae_u8 b = autoconfig[i];
1394 		ew(ide, i * 4, b);
1395 	}
1396 	if (cpuboard) {
1397 		ide->mask = 131072 - 1;
1398 		struct zfile *z = read_device_from_romconfig(rc, ROMTYPE_APOLLO);
1399 		if (z) {
1400 			int len = zfile_size(z);
1401 			// skip 68060 $f0 ROM block
1402 			if (len >= 65536)
1403 				zfile_fseek(z, 32768, SEEK_SET);
1404 			for (int i = 0; i < 32768; i++) {
1405 				uae_u8 b;
1406 				zfile_fread(&b, 1, 1, z);
1407 				ide->rom[i] = b;
1408 			}
1409 			zfile_fclose(z);
1410 		}
1411 	} else {
1412 		ide->mask = 65536 - 1;
1413 		load_rom_rc(rc, ROMTYPE_APOLLO, 16384, 0, ide->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
1414 	}
1415 	return ide->bank;
1416 }
1417 
apollo_init_hd(struct romconfig * rc)1418 addrbank *apollo_init_hd(struct romconfig *rc)
1419 {
1420 	return apollo_init(rc, false);
1421 }
apollo_init_cpu(struct romconfig * rc)1422 addrbank *apollo_init_cpu(struct romconfig *rc)
1423 {
1424 	return apollo_init(rc, true);
1425 }
1426 
apollo_add_ide_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1427 void apollo_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1428 {
1429 	add_ide_standard_unit(ch, ci, rc, apollo_board, APOLLO_IDE, true, false, 2);
1430 }
1431 
masoboshi_init(struct romconfig * rc)1432 addrbank *masoboshi_init(struct romconfig *rc)
1433 {
1434 	struct ide_board *ide = getide(rc);
1435 
1436 	if (!ide)
1437 		return &expamem_null;
1438 
1439 	ide->configured = 0;
1440 
1441 	ide->configured = 0;
1442 	ide->bank = &ide_bank_generic;
1443 	ide->type = MASOBOSHI_IDE;
1444 	ide->rom_size = 65536;
1445 	ide->mask = 65536 - 1;
1446 	ide->subtype = 0;
1447 
1448 	ide->rom = xcalloc(uae_u8, ide->rom_size);
1449 	memset(ide->rom, 0xff, ide->rom_size);
1450 	memset(ide->acmemory, 0xff, sizeof ide->acmemory);
1451 	ide->rom_mask = ide->rom_size - 1;
1452 
1453 	load_rom_rc(rc, ROMTYPE_MASOBOSHI, 32768, 0, ide->rom, 65536, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
1454 	ide->subtype = rc->subtype;
1455 	if (rc && rc->autoboot_disabled)
1456 		memcpy(ide->acmemory, ide->rom + 0x100, sizeof ide->acmemory);
1457 	else
1458 		memcpy(ide->acmemory, ide->rom + 0x000, sizeof ide->acmemory);
1459 
1460 	return ide->bank;
1461 }
1462 
masoboshi_add_ide_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1463 static void masoboshi_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1464 {
1465 	add_ide_standard_unit(ch, ci, rc, masoboshi_board, MASOBOSHI_IDE, true, false, 2);
1466 }
1467 
masoboshi_add_idescsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1468 void masoboshi_add_idescsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1469 {
1470 	if (ch < 0) {
1471 		masoboshi_add_ide_unit(ch, ci, rc);
1472 		masoboshi_add_scsi_unit(ch, ci, rc);
1473 	} else {
1474 		if (ci->controller_type < HD_CONTROLLER_TYPE_SCSI_FIRST)
1475 			masoboshi_add_ide_unit(ch, ci, rc);
1476 		else
1477 			masoboshi_add_scsi_unit(ch, ci, rc);
1478 	}
1479 }
1480 
1481 static const uae_u8 adide_autoconfig[16] = { 0xd1, 0x02, 0x00, 0x00, 0x08, 0x17, 0x00, 0x00, 0x00, 0x00, ADIDE_ROM_OFFSET >> 8, ADIDE_ROM_OFFSET & 0xff };
1482 
adide_init(struct romconfig * rc)1483 addrbank *adide_init(struct romconfig *rc)
1484 {
1485 	struct ide_board *ide = getide(rc);
1486 
1487 	ide->configured = 0;
1488 	ide->keepautoconfig = false;
1489 	ide->bank = &ide_bank_generic;
1490 	ide->rom_size = 32768;
1491 	ide->mask = 65536 - 1;
1492 
1493 	memset(ide->acmemory, 0xff, sizeof ide->acmemory);
1494 
1495 	ide->rom = xcalloc(uae_u8, ide->rom_size);
1496 	memset(ide->rom, 0xff, ide->rom_size);
1497 	ide->rom_mask = ide->rom_size - 1;
1498 	if (!rc->autoboot_disabled) {
1499 		load_rom_rc(rc, ROMTYPE_ADIDE, 16384, 0, ide->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
1500 	}
1501 	for (int i = 0; i < 16; i++) {
1502 		uae_u8 b = adide_autoconfig[i];
1503 		ew(ide, i * 4, b);
1504 	}
1505 	return ide->bank;
1506 }
1507 
adide_add_ide_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1508 void adide_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1509 {
1510 	add_ide_standard_unit(ch, ci, rc, adide_board, ADIDE_IDE, false, true, 2);
1511 }
1512 
mtec_init(struct romconfig * rc)1513 addrbank *mtec_init(struct romconfig *rc)
1514 {
1515 	struct ide_board *ide = getide(rc);
1516 
1517 	ide->configured = 0;
1518 	ide->bank = &ide_bank_generic;
1519 	ide->rom_size = 32768;
1520 	ide->mask = 65536 - 1;
1521 
1522 	ide->rom = xcalloc(uae_u8, ide->rom_size);
1523 	memset(ide->rom, 0xff, ide->rom_size);
1524 	ide->rom_mask = ide->rom_size - 1;
1525 	load_rom_rc(rc, ROMTYPE_MTEC, 16384, !rc->autoboot_disabled ? 16384 : 0, ide->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
1526 	memcpy(ide->acmemory, ide->rom, sizeof ide->acmemory);
1527 	return ide->bank;
1528 }
1529 
mtec_add_ide_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1530 void mtec_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1531 {
1532 	add_ide_standard_unit(ch, ci, rc, mtec_board, MTEC_IDE, false, false, 2);
1533 }
1534 
rochard_init(struct romconfig * rc)1535 addrbank *rochard_init(struct romconfig *rc)
1536 {
1537 	struct ide_board *ide = getide(rc);
1538 
1539 	ide->configured = 0;
1540 	ide->bank = &ide_bank_generic;
1541 	ide->rom_size = 32768;
1542 	ide->mask = 65536 - 1;
1543 	ide->subtype = rc->subtype;
1544 
1545 	ide->rom = xcalloc(uae_u8, ide->rom_size);
1546 	memset(ide->rom, 0xff, ide->rom_size);
1547 	ide->rom_mask = ide->rom_size - 1;
1548 	load_rom_rc(rc, ROMTYPE_ROCHARD, 8192, !rc->autoboot_disabled ? 8192 : 0, ide->rom, 16384, 0);
1549 	memcpy(ide->acmemory, ide->rom, sizeof ide->acmemory);
1550 	return ide->bank;
1551 }
1552 
rochard_add_ide_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1553 static void rochard_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1554 {
1555 	add_ide_standard_unit(ch, ci, rc, rochard_board, ROCHARD_IDE, false, false, 4);
1556 }
1557 
rochard_add_idescsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1558 void rochard_add_idescsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1559 {
1560 	if (ch < 0) {
1561 		rochard_add_ide_unit(ch, ci, rc);
1562 		rochard_add_scsi_unit(ch, ci, rc);
1563 	} else {
1564 		if (ci->controller_type < HD_CONTROLLER_TYPE_SCSI_FIRST)
1565 			rochard_add_ide_unit(ch, ci, rc);
1566 		else
1567 			rochard_add_scsi_unit(ch, ci, rc);
1568 	}
1569 }
1570 
golemfast_init(struct romconfig * rc)1571 addrbank *golemfast_init(struct romconfig *rc)
1572 {
1573 	struct ide_board *ide = getide(rc);
1574 
1575 	ide->configured = 0;
1576 	ide->bank = &ide_bank_generic;
1577 	ide->rom_size = 32768;
1578 	ide->mask = 65536 - 1;
1579 
1580 	ide->rom = xcalloc(uae_u8, ide->rom_size);
1581 	memset(ide->rom, 0xff, ide->rom_size);
1582 	ide->rom_mask = ide->rom_size - 1;
1583 	load_rom_rc(rc, ROMTYPE_GOLEMFAST, 16384, 0, ide->rom, 32768, 0);
1584 	memcpy(ide->acmemory, ide->rom, sizeof ide->acmemory);
1585 	return ide->bank;
1586 }
1587 
golemfast_add_ide_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1588 static void golemfast_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1589 {
1590 	add_ide_standard_unit(ch, ci, rc, golemfast_board, GOLEMFAST_IDE, false, false, 2);
1591 }
1592 
golemfast_add_idescsi_unit(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1593 void golemfast_add_idescsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1594 {
1595 	if (ch < 0) {
1596 		golemfast_add_ide_unit(ch, ci, rc);
1597 		golemfast_add_scsi_unit(ch, ci, rc);
1598 	} else {
1599 		if (ci->controller_type < HD_CONTROLLER_TYPE_SCSI_FIRST)
1600 			golemfast_add_ide_unit(ch, ci, rc);
1601 		else
1602 			golemfast_add_scsi_unit(ch, ci, rc);
1603 	}
1604 }
1605 
1606 
1607 extern void x86_xt_ide_bios(struct zfile*, struct romconfig*);
x86_at_hd_init(struct romconfig * rc,int type)1608 static addrbank *x86_at_hd_init(struct romconfig *rc, int type)
1609 {
1610 	struct ide_board *ide = getide(rc);
1611 
1612 	if (!ide)
1613 		return NULL;
1614 
1615 	ide->intena = type == 0;
1616 	ide->configured = 1;
1617 	ide->bank = &ide_bank_generic;
1618 
1619 	struct zfile *f = read_device_from_romconfig(rc, 0);
1620 	if (f) {
1621 		x86_xt_ide_bios(f, rc);
1622 		zfile_fclose(f);
1623 	}
1624 
1625 	return NULL;
1626 }
x86_at_hd_init_1(struct romconfig * rc)1627 addrbank *x86_at_hd_init_1(struct romconfig *rc)
1628 {
1629 	return x86_at_hd_init(rc, 0);
1630 }
x86_at_hd_init_2(struct romconfig * rc)1631 addrbank *x86_at_hd_init_2(struct romconfig *rc)
1632 {
1633 	return x86_at_hd_init(rc, 0);
1634 }
x86_at_hd_init_xt(struct romconfig * rc)1635 addrbank *x86_at_hd_init_xt(struct romconfig *rc)
1636 {
1637 	return x86_at_hd_init(rc, 1);
1638 }
1639 
x86_add_at_hd_unit_1(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1640 void x86_add_at_hd_unit_1(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1641 {
1642 	add_ide_standard_unit(ch, ci, rc, &x86_at_ide_board[0], x86_AT_IDE + 0, false, false, 2);
1643 }
x86_add_at_hd_unit_2(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1644 void x86_add_at_hd_unit_2(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1645 {
1646 	add_ide_standard_unit(ch, ci, rc, &x86_at_ide_board[1], x86_AT_IDE + 1, false, false, 2);
1647 }
x86_add_at_hd_unit_xt(int ch,struct uaedev_config_info * ci,struct romconfig * rc)1648 void x86_add_at_hd_unit_xt(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1649 {
1650 	add_ide_standard_unit(ch, ci, rc, &x86_at_ide_board[2], x86_AT_IDE + 2, false, false, 2);
1651 }
1652 
x86_ide_reg(int portnum,int * unit)1653 static int x86_ide_reg(int portnum, int *unit)
1654 {
1655 	if (portnum >= 0x1f0 && portnum < 0x1f8) {
1656 		*unit = 0;
1657 		return portnum & 7;
1658 	}
1659 	if (portnum == 0x3f6) {
1660 		*unit = 0;
1661 		return 6 | IDE_SECONDARY;
1662 	}
1663 	if (portnum >= 0x170 && portnum < 0x178) {
1664 		*unit = 1;
1665 		return portnum & 7;
1666 	}
1667 	if (portnum == 0x376) {
1668 		*unit = 1;
1669 		return 6 | IDE_SECONDARY;
1670 	}
1671 	if (portnum >= 0x300 && portnum < 0x310) {
1672 		*unit = 2;
1673 		if (portnum < 0x308)
1674 			return portnum & 7;
1675 		if (portnum == 0x308)
1676 			return 8;
1677 		if (portnum >= 0x308+6)
1678 			return (portnum & 7) | IDE_SECONDARY;
1679 	}
1680 	return -1;
1681 }
1682 
x86_ide_hd_put(int portnum,uae_u16 v,int size)1683 void x86_ide_hd_put(int portnum, uae_u16 v, int size)
1684 {
1685 
1686 	if (portnum < 0) {
1687 		for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) {
1688 			struct ide_board *board = x86_at_ide_board[i];
1689 			if (board)
1690 				ide_reset_device(board->ide[0]);
1691 		}
1692 		return;
1693 	}
1694 	int unit;
1695 	int regnum = x86_ide_reg(portnum, &unit);
1696 	if (regnum >= 0) {
1697 		struct ide_board *board = x86_at_ide_board[unit];
1698 		if (board) {
1699 #if 0
1700 			if (regnum == 0 || regnum == 8)
1701 				write_log(_T("WRITE %04x = %04x %d\n"), portnum, v, size);
1702 #endif
1703 			if (size == 0) {
1704 				if (get_ide_is_8bit(board)) {
1705 					v = get_ide_reg_8bitdata(board, regnum);
1706 				} else {
1707 					if (regnum == 8) {
1708 						board->data_latch = v;
1709 					} else if (regnum == 0) {
1710 						v <<= 8;
1711 						v |= board->data_latch;
1712 						put_ide_reg(board, regnum, v);
1713 					} else {
1714 						put_ide_reg_8bitdata(board, regnum, v);
1715 					}
1716 				}
1717 			} else {
1718 				put_ide_reg(board, regnum, (v >> 8) | (v << 8));
1719 			}
1720 		}
1721 	}
1722 }
x86_ide_hd_get(int portnum,int size)1723 uae_u16 x86_ide_hd_get(int portnum, int size)
1724 {
1725 	uae_u16 v = 0;
1726 	int unit;
1727 	int regnum = x86_ide_reg(portnum, &unit);
1728 	if (regnum >= 0) {
1729 		struct ide_board *board = x86_at_ide_board[unit];
1730 		if (board) {
1731 
1732 			if (size == 0) {
1733 				if (get_ide_is_8bit(board)) {
1734 					v = get_ide_reg_8bitdata(board, regnum);
1735 				} else {
1736 					if (regnum == 0) {
1737 						board->data_latch = get_ide_reg(board, regnum);
1738 						v = board->data_latch >> 8;
1739 					} else if (regnum == 8) {
1740 						v = board->data_latch;
1741 					} else {
1742 						v = get_ide_reg_8bitdata(board, regnum & 7);
1743 					}
1744 				}
1745 			} else {
1746 				v = get_ide_reg(board, regnum);
1747 				v = (v >> 8) | (v << 8);
1748 			}
1749 #if 0
1750 			if (regnum == 0 || regnum == 8)
1751 				write_log(_T("READ %04x = %04x %d\n"), portnum, v, size);
1752 #endif
1753 		}
1754 	}
1755 	return v;
1756 }
1757