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