1 #include <stdlib.h>
2 #include "ibm.h"
3 #include "device.h"
4 #include "io.h"
5 #include "mem.h"
6 #include "rom.h"
7 #include "scsi.h"
8 #include "scsi_53c400.h"
9 #include "timer.h"
10 
11 #define POLL_TIME_US 10
12 #define MAX_BYTES_TRANSFERRED_PER_POLL 50
13 /*10us poll period with 50 bytes transferred per poll = 5MB/sec*/
14 
15 typedef struct ncr5380_t
16 {
17 	uint8_t output_data;
18 	uint8_t icr;
19 	uint8_t mode;
20 	uint8_t tcr;
21 	uint8_t ser;
22 	uint8_t isr;
23 
24 	int target_id;
25 	int target_bsy;
26 	int target_req;
27 
28 	uint8_t bus_status;
29 
30 	int dma_mode;
31 
32 	void (*dma_changed)(struct ncr5380_t *ncr, int mode, int enable);
33 	void *p;
34 
35 	scsi_bus_t bus;
36 } ncr5380_t;
37 
38 typedef struct lcs6821n_t
39 {
40         rom_t bios_rom;
41 
42         mem_mapping_t mapping;
43 
44         uint8_t block_count;
45         int block_count_loaded;
46 
47         uint8_t status_ctrl;
48 
49         uint8_t buffer[0x80];
50         int buffer_pos;
51         int buffer_host_pos;
52 
53         uint8_t int_ram[0x40];
54         uint8_t ext_ram[0x600];
55 
56         ncr5380_t ncr;
57 
58         int ncr5380_dma_enabled;
59 
60         int dma_callback;
61         int dma_enabled;
62 
63         int ncr_busy;
64 } lcs6821n_t;
65 
66 #define ICR_DBP             0x01
67 #define ICR_ATN             0x02
68 #define ICR_SEL             0x04
69 #define ICR_BSY             0x08
70 #define ICR_ACK             0x10
71 #define ICR_ARB_LOST        0x20
72 #define ICR_ARB_IN_PROGRESS 0x40
73 
74 #define MODE_ARBITRATE 0x01
75 #define MODE_DMA       0x02
76 #define MODE_MONITOR_BUSY  0x04
77 #define MODE_ENA_EOP_INT   0x08
78 
79 #define STATUS_ACK 0x01
80 #define STATUS_BUSY_ERROR 0x04
81 #define STATUS_INT 0x10
82 #define STATUS_DRQ 0x40
83 #define STATUS_END_OF_DMA 0x80
84 
85 #define TCR_IO  0x01
86 #define TCR_CD  0x02
87 #define TCR_MSG 0x04
88 #define TCR_REQ 0x08
89 #define TCR_LAST_BYTE_SENT 0x80
90 
91 enum
92 {
93         DMA_IDLE = 0,
94         DMA_SEND,
95         DMA_TARGET_RECEIVE,
96         DMA_INITIATOR_RECEIVE
97 };
98 
ncr53c400_dma_changed(ncr5380_t * ncr,int mode,int enable)99 static void ncr53c400_dma_changed(ncr5380_t *ncr, int mode, int enable)
100 {
101         lcs6821n_t *scsi = (lcs6821n_t *)ncr->p;
102 
103         scsi->ncr5380_dma_enabled = (mode && enable);
104 
105         scsi->dma_enabled = (scsi->ncr5380_dma_enabled && scsi->block_count_loaded);
106 }
107 
ncr5380_reset(ncr5380_t * ncr)108 void ncr5380_reset(ncr5380_t *ncr)
109 {
110 	memset(ncr, 0, sizeof(ncr5380_t));
111 }
112 
get_bus_host(ncr5380_t * ncr)113 static uint32_t get_bus_host(ncr5380_t *ncr)
114 {
115         uint32_t bus_host = 0;
116 
117 	if (ncr->icr & ICR_DBP)
118 		bus_host |= BUS_DBP;
119 	if (ncr->icr & ICR_SEL)
120 		bus_host |= BUS_SEL;
121 	if (ncr->icr & ICR_ATN)
122 		bus_host |= BUS_ATN;
123         if (ncr->tcr & TCR_IO)
124 		bus_host |= BUS_IO;
125 	if (ncr->tcr & TCR_CD)
126 		bus_host |= BUS_CD;
127 	if (ncr->tcr & TCR_MSG)
128 		bus_host |= BUS_MSG;
129 	if (ncr->tcr & TCR_REQ)
130 		bus_host |= BUS_REQ;
131 	if (ncr->icr & ICR_BSY)
132 		bus_host |= BUS_BSY;
133 	if (ncr->icr & ICR_ACK)
134 		bus_host |= BUS_ACK;
135 	if (ncr->mode & MODE_ARBITRATE)
136 	        bus_host |= BUS_ARB;
137 //	pclog("get_bus_host %02x %08x\n",  ncr->output_data, BUS_SETDATA(ncr->output_data));
138 	return bus_host | BUS_SETDATA(ncr->output_data);
139 }
140 
ncr5380_write(uint32_t addr,uint8_t val,void * p)141 void ncr5380_write(uint32_t addr, uint8_t val, void *p)
142 {
143         ncr5380_t *ncr = (ncr5380_t *)p;
144         int bus_host = 0;
145 
146 //	pclog("ncr5380_write: addr=%06x val=%02x %04x:%04x\n", addr, val, CS,cpu_state.pc);
147 	switch (addr & 7)
148 	{
149 		case 0: /*Output data register*/
150 		ncr->output_data = val;
151 		break;
152 
153 		case 1: /*Initiator Command Register*/
154 		if ((val & (ICR_BSY | ICR_SEL)) == (ICR_BSY | ICR_SEL) &&
155 		    (ncr->icr & (ICR_BSY | ICR_SEL)) == ICR_SEL)
156 		{
157 			uint8_t temp = ncr->output_data & 0x7f;
158 
159 			ncr->target_id = -1;
160 			while (temp)
161 			{
162 				temp >>= 1;
163 				ncr->target_id++;
164 			}
165 //			pclog("Select - target ID = %i\n", ncr->target_id);
166 
167 			if (!ncr->target_id)
168 				ncr->target_bsy = 1;
169 		}
170 
171 		ncr->icr = val;
172 		break;
173 
174 		case 2: /*Mode register*/
175 		if ((val & MODE_ARBITRATE) && !(ncr->mode & MODE_ARBITRATE))
176 		{
177 			ncr->icr &= ~ICR_ARB_LOST;
178 			ncr->icr |=  ICR_ARB_IN_PROGRESS;
179 		}
180 
181 //		output = 1;
182 		ncr->mode = val;
183 		ncr->dma_changed(ncr, ncr->dma_mode, ncr->mode & MODE_DMA);
184 		if (!(ncr->mode & MODE_DMA))
185 		{
186                         ncr->tcr &= ~TCR_LAST_BYTE_SENT;
187         		ncr->isr &= ~STATUS_END_OF_DMA;
188         		ncr->dma_mode = DMA_IDLE;
189                 }
190 		break;
191 
192 		case 3: /*Target Command Register*/
193 		ncr->tcr = val;
194 /*		switch (val & (TCR_MSG | TCR_CD | TCR_IO))
195 		{
196 			case TCR_CD:
197 			ncr->target_req = 1;
198 			break;
199 		}*/
200 		break;
201 		case 4: /*Select Enable Register*/
202 		ncr->ser = val;
203 		break;
204 
205 		case 5: /*Start DMA Send*/
206 		ncr->dma_mode = DMA_SEND;
207 		ncr->dma_changed(ncr, ncr->dma_mode, ncr->mode & MODE_DMA);
208 		break;
209 
210 		case 7: /*Start DMA Initiator Receive*/
211 		ncr->dma_mode = DMA_INITIATOR_RECEIVE;
212 		ncr->dma_changed(ncr, ncr->dma_mode, ncr->mode & MODE_DMA);
213 		break;
214 
215 		default:
216 		pclog("Bad NCR5380 write %06x %02x\n", addr, val);
217 	}
218 
219         bus_host = get_bus_host(ncr);
220 
221         scsi_bus_update(&ncr->bus, bus_host);
222 }
223 
ncr5380_read(uint32_t addr,void * p)224 uint8_t ncr5380_read(uint32_t addr, void *p)
225 {
226         ncr5380_t *ncr = (ncr5380_t *)p;
227         uint32_t bus = 0;
228 	uint8_t temp = 0xff;
229 
230 	switch (addr & 7)
231 	{
232 		case 0: /*Current SCSI Data*/
233 		//output = 3;
234 		//fatal("Here\n");
235 		if (ncr->icr & ICR_DBP)
236 		      temp = ncr->output_data;
237 		else
238 		{
239                 	bus = scsi_bus_read(&ncr->bus);
240         		temp = BUS_GETDATA(bus);
241                 }
242 		break;
243 		case 1: /*Initiator Command Register*/
244 		temp = ncr->icr;
245 		break;
246 		case 2: /*Mode Register*/
247 		temp = ncr->mode;
248 		break;
249 		case 3: /*Target Command Register*/
250 		temp = ncr->tcr;
251 		break;
252 
253 		case 4: /*Current SCSI Bus Status*/
254 		temp = 0;//get_bus_host(ncr);
255         	bus = scsi_bus_read(&ncr->bus);
256 //        	pclog("  SCSI bus status = %02x %02x\n", temp, bus);
257         	temp |= (bus & 0xff);
258 //		pclog("  SCSI bus status = %02x\n", temp);
259 		break;
260 
261 		case 5: /*Bus and Status Register*/
262 		temp = 0;
263 
264                 bus = get_bus_host(ncr);
265                 if (scsi_bus_match(&ncr->bus, bus))
266                         temp |= 8;
267         	bus = scsi_bus_read(&ncr->bus);
268 
269                 if (bus & BUS_ACK)
270                         temp |= STATUS_ACK;
271                 if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA))
272                         temp |= STATUS_DRQ;
273                 if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA))
274                 {
275                         int bus_state = 0;
276                         if (bus & BUS_IO)
277                                 bus_state |= TCR_IO;
278                         if (bus & BUS_CD)
279                                 bus_state |= TCR_CD;
280                         if (bus & BUS_MSG)
281                                 bus_state |= TCR_MSG;
282                         if ((ncr->tcr & 7) != bus_state)
283                                 ncr->isr |= STATUS_INT;
284                 }
285                 if (!(bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY))
286                         temp |= STATUS_BUSY_ERROR;
287                 temp |= (ncr->isr & (STATUS_INT | STATUS_END_OF_DMA));
288 
289 //                pclog("  bus and status register = %02x\n", temp);
290 		break;
291 
292 		case 7: /*Reset Parity/Interrupt*/
293 		ncr->isr &= ~STATUS_INT;
294 		break;
295 
296 		default:
297 		pclog("Bad NCR5380 read %06x\n", addr);
298 	}
299 //	pclog("ncr5380_read: addr=%06x temp=%02x pc=%04x:%04x\n", addr, temp, CS,cpu_state.pc);
300 	return temp;
301 }
302 
303 #define CTRL_DATA_DIR (1 << 6)
304 
305 #define STATUS_BUFFER_NOT_READY (1 << 2)
306 #define STATUS_53C80_ACCESSIBLE (1 << 7)
307 
lcs6821n_read(uint32_t addr,void * p)308 static uint8_t lcs6821n_read(uint32_t addr, void *p)
309 {
310         lcs6821n_t *scsi = (lcs6821n_t *)p;
311         uint8_t temp = 0xff;
312 //if (addr >= 0xca000)
313         addr &= 0x3fff;
314 //        pclog("lcs6821n_read %08x\n", addr);
315         if (addr < 0x2000)
316                 temp = scsi->bios_rom.rom[addr & 0x1fff];
317         else if (addr < 0x3800)
318                 temp = 0xff;
319         else if (addr >= 0x3a00)
320                 temp = scsi->ext_ram[addr - 0x3a00];
321         else switch (addr & 0x3f80)
322         {
323                 case 0x3800:
324 //                pclog("Read intRAM %02x %02x\n", addr & 0x3f, scsi->int_ram[addr & 0x3f]);
325                 temp = scsi->int_ram[addr & 0x3f];
326                 break;
327 
328                 case 0x3880:
329 //                pclog("Read 53c80 %04x\n", addr);
330                 temp = ncr5380_read(addr, &scsi->ncr);
331                 break;
332 
333                 case 0x3900:
334 //pclog(" Read 3900 %i %02x\n", scsi->buffer_host_pos, scsi->status_ctrl);
335                 if (scsi->buffer_host_pos >= 128 || !(scsi->status_ctrl & CTRL_DATA_DIR))
336                         temp = 0xff;
337                 else
338                 {
339                         temp = scsi->buffer[scsi->buffer_host_pos++];
340 
341                         if (scsi->buffer_host_pos == 128)
342                                 scsi->status_ctrl |= STATUS_BUFFER_NOT_READY;
343                 }
344                 break;
345 
346                 case 0x3980:
347                 switch (addr)
348                 {
349                         case 0x3980: /*Status*/
350                         temp = scsi->status_ctrl;// | 0x80;
351                         if (!scsi->ncr_busy)
352                                 temp |= STATUS_53C80_ACCESSIBLE;
353                         break;
354                         case 0x3981: /*Block counter register*/
355                         temp = scsi->block_count;
356                         break;
357                         case 0x3982: /*Switch register read*/
358 //                        temp = 7 | (7 << 3);
359                         temp = 0xff;
360                         break;
361                         case 0x3983:
362                         temp = 0xff;
363                         break;
364                 }
365                 break;
366         }
367 
368 //        if (addr >= 0x3880) pclog("lcs6821n_read: addr=%05x val=%02x %04x:%04x\n", addr, temp, CS,cpu_state.pc);
369 
370         return temp;
371 }
372 
lcs6821n_write(uint32_t addr,uint8_t val,void * p)373 static void lcs6821n_write(uint32_t addr, uint8_t val, void *p)
374 {
375         lcs6821n_t *scsi = (lcs6821n_t *)p;
376 
377         addr &= 0x3fff;
378 
379 //        /*if (addr >= 0x3880) */pclog("lcs6821n_write: addr=%05x val=%02x %04x:%04x  %i %02x\n", addr, val, CS,cpu_state.pc,  scsi->buffer_host_pos, scsi->status_ctrl);
380 
381         if (addr >= 0x3a00)
382                 scsi->ext_ram[addr - 0x3a00] = val;
383         else switch (addr & 0x3f80)
384         {
385                 case 0x3800:
386 //                pclog("Write intram %02x %02x\n", addr & 0x3f, val);
387                 scsi->int_ram[addr & 0x3f] = val;
388                 break;
389 
390                 case 0x3880:
391 //                pclog("Write 53c80 %04x %02x\n", addr, val);
392                 ncr5380_write(addr, val, &scsi->ncr);
393                 break;
394 
395                 case 0x3900:
396                 if (!(scsi->status_ctrl & CTRL_DATA_DIR) && scsi->buffer_host_pos < 128)
397                 {
398 //                        pclog("  Write %i %02x\n", scsi->buffer_host_pos, val);
399                         scsi->buffer[scsi->buffer_host_pos++] = val;
400                         if (scsi->buffer_host_pos == 128)
401                         {
402                                 scsi->status_ctrl |= STATUS_BUFFER_NOT_READY;
403                                 scsi->ncr_busy = 1;
404                         }
405                 }
406                 break;
407 
408                 case 0x3980:
409                 switch (addr)
410                 {
411                         case 0x3980: /*Control*/
412                         if ((val & CTRL_DATA_DIR) && !(scsi->status_ctrl & CTRL_DATA_DIR))
413                         {
414                                 scsi->buffer_host_pos = 128;
415                                 scsi->status_ctrl |= STATUS_BUFFER_NOT_READY;
416                         }
417                         else if (!(val & CTRL_DATA_DIR) && (scsi->status_ctrl & CTRL_DATA_DIR))
418                         {
419                                 scsi->buffer_host_pos = 0;
420                                 scsi->status_ctrl &= ~STATUS_BUFFER_NOT_READY;
421                         }
422                         scsi->status_ctrl = (scsi->status_ctrl & 0x87) | (val & 0x78);
423                         break;
424                         case 0x3981: /*Block counter register*/
425                         scsi->block_count = val;
426                         scsi->block_count_loaded = 1;
427                         scsi->dma_enabled = (scsi->ncr5380_dma_enabled && scsi->block_count_loaded);
428                         if (scsi->status_ctrl & CTRL_DATA_DIR)
429                         {
430                                 scsi->buffer_host_pos = 128;
431                                 scsi->status_ctrl |= STATUS_BUFFER_NOT_READY;
432                         }
433                         else
434                         {
435                                 scsi->buffer_host_pos = 0;
436                                 scsi->status_ctrl &= ~STATUS_BUFFER_NOT_READY;
437                         }
438                         break;
439                 }
440                 break;
441         }
442 }
443 
t130b_read(uint32_t addr,void * p)444 static uint8_t t130b_read(uint32_t addr, void *p)
445 {
446         lcs6821n_t *scsi = (lcs6821n_t *)p;
447         uint8_t temp = 0xff;
448 //if (addr >= 0xca000)
449         addr &= 0x3fff;
450 
451         if (addr < 0x1800)
452                 temp = scsi->bios_rom.rom[addr & 0x1fff];
453         else if (addr < 0x1880)
454                 temp = scsi->ext_ram[addr & 0x7f];
455 //        else
456 //                pclog("Bad T130B read %04x\n", addr);
457 
458 //        if (addr >= 0x3880) pclog("lcs6821n_read: addr=%05x val=%02x %04x:%04x\n", addr, temp, CS,cpu_state.pc);
459 
460         return temp;
461 }
t130b_write(uint32_t addr,uint8_t val,void * p)462 static void t130b_write(uint32_t addr, uint8_t val, void *p)
463 {
464         lcs6821n_t *scsi = (lcs6821n_t *)p;
465 
466         addr &= 0x3fff;
467 
468 //        if (addr >= 0x3880) pclog("lcs6821n_write: addr=%05x val=%02x %04x:%04x  %i %02x\n", addr, val, CS,cpu_state.pc,  scsi->buffer_host_pos, scsi->status_ctrl);
469 
470         if (addr >= 0x1800 && addr < 0x1880)
471                 scsi->ext_ram[addr & 0x7f] = val;
472 //        else
473 //                pclog("Bad T130B write %04x %02x\n", addr, val);
474 }
475 
t130b_in(uint16_t port,void * p)476 static uint8_t t130b_in(uint16_t port, void *p)
477 {
478         lcs6821n_t *scsi = (lcs6821n_t *)p;
479         uint8_t temp = 0xff;
480 
481         switch (port & 0xf)
482         {
483                 case 0x0: case 0x1: case 0x2: case 0x3:
484                 temp = lcs6821n_read((port & 7) | 0x3980, scsi);
485                 break;
486 
487                 case 0x4: case 0x5:
488                 temp = lcs6821n_read(0x3900, scsi);
489                 break;
490 
491                 case 0x8: case 0x9: case 0xa: case 0xb:
492                 case 0xc: case 0xd: case 0xe: case 0xf:
493                 temp = ncr5380_read(port, &scsi->ncr);
494                 break;
495         }
496 
497         if (CS != 0xdc00)
498         {
499                 //pclog("t130b_in: port=%04x val=%02x %04x:%04x\n", port, temp, CS,cpu_state.pc);
500                 //output = 3;
501                 //fatal("Here\n");
502         }
503         return temp;
504 }
t130b_out(uint16_t port,uint8_t val,void * p)505 static void t130b_out(uint16_t port, uint8_t val, void *p)
506 {
507         lcs6821n_t *scsi = (lcs6821n_t *)p;
508 
509         //if (CS != 0xdc00) pclog("t130b_out: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc);
510 
511         switch (port & 0xf)
512         {
513                 case 0x0: case 0x1: case 0x2: case 0x3:
514                 lcs6821n_write((port & 7) | 0x3980, val, scsi);
515                 break;
516 
517                 case 0x4: case 0x5:
518                 lcs6821n_write(0x3900, val, scsi);
519                 break;
520 
521                 case 0x8: case 0x9: case 0xa: case 0xb:
522                 case 0xc: case 0xd: case 0xe: case 0xf:
523                 ncr5380_write(port, val, &scsi->ncr);
524                 break;
525         }
526 }
527 
ncr53c400_dma_callback(void * p)528 static void ncr53c400_dma_callback(void *p)
529 {
530         lcs6821n_t *scsi = (lcs6821n_t *)p;
531         ncr5380_t *ncr = &scsi->ncr;
532         int c;
533         int bytes_transferred = 0;
534 
535 //pclog("dma_Callback poll\n");
536         scsi->dma_callback += POLL_TIME_US;
537 
538         switch (scsi->ncr.dma_mode)
539         {
540                 case DMA_SEND:
541                 if (scsi->status_ctrl & CTRL_DATA_DIR)
542                 {
543                         pclog("DMA_SEND with DMA direction set wrong\n");
544                         break;
545                 }
546 
547 //                if (!device_data[ncr->target_id])
548 //                        fatal("DMA with no device\n");
549 
550                 if (!(scsi->status_ctrl & STATUS_BUFFER_NOT_READY))
551                 {
552 //                        pclog(" !(scsi->status_ctrl & STATUS_BUFFER_NOT_READY)\n");
553                         break;
554                 }
555 
556                 if (!scsi->block_count_loaded)
557                 {
558 //                        pclog("!scsi->block_count_loaded\n");
559                         break;
560                 }
561 
562                 while (bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL)
563                 {
564                         int bus;
565                         uint8_t data;
566 
567                         for (c = 0; c < 10; c++)
568                         {
569                                 uint8_t status = scsi_bus_read(&ncr->bus);
570 
571                                 if (status & BUS_REQ)
572                                         break;
573                         }
574                         if (c == 10)
575                         {
576 //                                pclog(" No req\n");
577                                 break;
578                         }
579 
580                         /*Data ready*/
581                         data = scsi->buffer[scsi->buffer_pos];
582                 	bus = get_bus_host(ncr) & ~BUS_DATAMASK;
583                         bus |= BUS_SETDATA(data);
584 
585                         scsi_bus_update(&ncr->bus, bus | BUS_ACK);
586                         scsi_bus_update(&ncr->bus, bus & ~BUS_ACK);
587 //                         pclog(" Sent data %02x %i\n", data, scsi->buffer_pos);
588 
589                         scsi->buffer_pos++;
590                         bytes_transferred++;
591 
592                         if (scsi->buffer_pos == 128)
593                         {
594                                 scsi->buffer_pos = 0;
595                                 scsi->buffer_host_pos = 0;
596                                 scsi->status_ctrl &= ~STATUS_BUFFER_NOT_READY;
597                                 scsi->block_count = (scsi->block_count - 1) & 255;
598                                 scsi->ncr_busy = 0;
599 //                                pclog("Sent buffer %i\n", scsi->block_count);
600                                 if (!scsi->block_count)
601                                 {
602                                         scsi->block_count_loaded = 0;
603                                         scsi->dma_enabled = 0;
604 //                                        scsi->buffer_host_pos = 128;
605 //                                        scsi->status_ctrl |= STATUS_BUFFER_NOT_READY;
606 
607                                         ncr->tcr |= TCR_LAST_BYTE_SENT;
608                                         ncr->isr |= STATUS_END_OF_DMA;
609                                         if (ncr->mode & MODE_ENA_EOP_INT)
610                                                 ncr->isr |= STATUS_INT;
611                                 }
612                                 break;
613                         }
614                 }
615                 break;
616 
617                 case DMA_INITIATOR_RECEIVE:
618                 if (!(scsi->status_ctrl & CTRL_DATA_DIR))
619                 {
620                         pclog("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n");
621                         break;
622                 }
623 
624                 if (!(scsi->status_ctrl & STATUS_BUFFER_NOT_READY))
625                         break;
626 
627                 if (!scsi->block_count_loaded)
628                         break;
629 
630                 while (bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL)
631                 {
632                         int bus;
633                         uint8_t temp;
634 
635                         for (c = 0; c < 10; c++)
636                         {
637                                 uint8_t status = scsi_bus_read(&ncr->bus);
638 
639                                 if (status & BUS_REQ)
640                                         break;
641                         }
642                         if (c == 10)
643                                 break;
644 
645                         /*Data ready*/
646         		bus = scsi_bus_read(&ncr->bus);
647         		temp = BUS_GETDATA(bus);
648 //                        pclog(" Got data %02x %i\n", temp, scsi->buffer_pos);
649 
650                 	bus = get_bus_host(ncr);
651 
652                         scsi_bus_update(&ncr->bus, bus | BUS_ACK);
653                         scsi_bus_update(&ncr->bus, bus & ~BUS_ACK);
654 
655                         scsi->buffer[scsi->buffer_pos++] = temp;
656                         bytes_transferred++;
657 
658                         if (scsi->buffer_pos == 128)
659                         {
660                                 scsi->buffer_pos = 0;
661                                 scsi->buffer_host_pos = 0;
662                                 scsi->status_ctrl &= ~STATUS_BUFFER_NOT_READY;
663                                 scsi->block_count = (scsi->block_count - 1) & 255;
664 //                                pclog("Got buffer %i\n", scsi->block_count);
665                                 if (!scsi->block_count)
666                                 {
667                                         scsi->block_count_loaded = 0;
668                                         scsi->dma_enabled = 0;
669 
670 //                                        output=3;
671                                         ncr->isr |= STATUS_END_OF_DMA;
672                                         if (ncr->mode & MODE_ENA_EOP_INT)
673                                                 ncr->isr |= STATUS_INT;
674                                 }
675                                 break;
676                         }
677                 }
678                 break;
679 
680                 default:
681                 pclog("DMA callback bad mode %i\n", scsi->ncr.dma_mode);
682                 break;
683         }
684 
685         {
686                 int bus = scsi_bus_read(&ncr->bus);
687 
688                 if (!(bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY))
689                 {
690                         ncr->mode &= ~MODE_DMA;
691                         ncr->dma_mode = DMA_IDLE;
692                 	ncr->dma_changed(ncr, ncr->dma_mode, ncr->mode & MODE_DMA);
693                 }
694         }
695 }
696 
scsi_53c400_init(char * bios_fn)697 static void *scsi_53c400_init(char *bios_fn)
698 {
699         lcs6821n_t *scsi = malloc(sizeof(lcs6821n_t));
700         memset(scsi, 0, sizeof(lcs6821n_t));
701 
702         rom_init(&scsi->bios_rom, bios_fn, 0xdc000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
703         mem_mapping_disable(&scsi->bios_rom.mapping);
704 
705         mem_mapping_add(&scsi->mapping, 0xdc000, 0x4000,
706                     lcs6821n_read, NULL, NULL,
707                     lcs6821n_write, NULL, NULL,
708                     scsi->bios_rom.rom, 0, scsi);
709 
710         ncr5380_reset(&scsi->ncr);
711 
712         scsi->ncr.dma_changed = ncr53c400_dma_changed;
713         scsi->ncr.p = scsi;
714 
715         scsi->status_ctrl = STATUS_BUFFER_NOT_READY;
716         scsi->buffer_host_pos = 128;
717 
718         scsi_bus_init(&scsi->ncr.bus);
719 
720         timer_add(ncr53c400_dma_callback, &scsi->dma_callback, &scsi->dma_enabled, scsi);
721 
722         return scsi;
723 }
724 
scsi_lcs6821n_init()725 static void *scsi_lcs6821n_init()
726 {
727         return scsi_53c400_init("Longshine LCS-6821N - BIOS version 1.04.bin");
728 }
scsi_rt1000b_init()729 static void *scsi_rt1000b_init()
730 {
731         return scsi_53c400_init("Rancho_RT1000_RTBios_version_8.10R.bin");
732 }
733 
scsi_t130b_init(char * bios_fn)734 static void *scsi_t130b_init(char *bios_fn)
735 {
736         lcs6821n_t *scsi = malloc(sizeof(lcs6821n_t));
737         memset(scsi, 0, sizeof(lcs6821n_t));
738 
739         rom_init(&scsi->bios_rom, "trantor_t130b_bios_v2.14.bin", 0xdc000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
740 
741         mem_mapping_add(&scsi->mapping, 0xdc000, 0x4000,
742                     t130b_read, NULL, NULL,
743                     t130b_write, NULL, NULL,
744                     scsi->bios_rom.rom, 0, scsi);
745         io_sethandler(0x0350, 0x0010,
746                         t130b_in, NULL, NULL,
747                         t130b_out, NULL, NULL,
748                         scsi);
749 
750         ncr5380_reset(&scsi->ncr);
751 
752         scsi->ncr.dma_changed = ncr53c400_dma_changed;
753         scsi->ncr.p = scsi;
754 
755         scsi->status_ctrl = STATUS_BUFFER_NOT_READY;
756         scsi->buffer_host_pos = 128;
757 
758         scsi_bus_init(&scsi->ncr.bus);
759 
760         timer_add(ncr53c400_dma_callback, &scsi->dma_callback, &scsi->dma_enabled, scsi);
761 
762         return scsi;
763 }
764 
scsi_53c400_close(void * p)765 static void scsi_53c400_close(void *p)
766 {
767         lcs6821n_t *scsi = (lcs6821n_t *)p;
768 
769         scsi_bus_close(&scsi->ncr.bus);
770 
771         free(scsi);
772 }
773 
scsi_lcs6821n_available()774 static int scsi_lcs6821n_available()
775 {
776         return rom_present("Longshine LCS-6821N - BIOS version 1.04.bin");
777 }
778 
scsi_rt1000b_available()779 static int scsi_rt1000b_available()
780 {
781         return rom_present("Rancho_RT1000_RTBios_version_8.10R.bin");
782 }
783 
scsi_t130b_available()784 static int scsi_t130b_available()
785 {
786         return rom_present("trantor_t130b_bios_v2.14.bin");
787 }
788 
789 device_t scsi_lcs6821n_device =
790 {
791         "Longshine LCS-6821N (SCSI)",
792         0,
793         scsi_lcs6821n_init,
794         scsi_53c400_close,
795         scsi_lcs6821n_available,
796         NULL,
797         NULL,
798         NULL,
799         NULL
800 };
801 
802 device_t scsi_rt1000b_device =
803 {
804         "Ranco RT1000B (SCSI)",
805         0,
806         scsi_rt1000b_init,
807         scsi_53c400_close,
808         scsi_rt1000b_available,
809         NULL,
810         NULL,
811         NULL,
812         NULL
813 };
814 
815 device_t scsi_t130b_device =
816 {
817         "Trantor T130B (SCSI)",
818         0,
819         scsi_t130b_init,
820         scsi_53c400_close,
821         scsi_t130b_available,
822         NULL,
823         NULL,
824         NULL,
825         NULL
826 };
827