#include "../machine/mtpr.h"
#include "../tahoevba/vbaparam.h"
#include "../tahoestand/udc.h"
#define MEMDISK 0x80000 /* Memory mapped disk at 1/2 Mega */
/* Some I/O addresses used to generate pulses for scopes */
#define scope_out(x) movob(OUT/**/x,0)
#define scope_in(x) dummy = *(char *)(IN/**/x)
* Universal disk controller driver for the Motorola M68000/IPC.
* Stand-alone version (no interrupts, etc.)
static struct UDPAC udpkt
= {
2, 0, 21, 0, 0, 0, 0, SECTSIZ
, {0, 0}, 0, 0, 3
long udstd
[] = { /* May be used some day to boot from any of
* several UDC controllers */
/*****************************************************
/*The next layout of major/minor number assignments are for the UDC
/* +----------------+-----+-+-+-----+
/* | Major device # | |D|R| FLS |
/* +----------------+-----+-+-+-----+
/* | | |_____ File system # ( 0-7 )
/* | |_________ Fixed (0) or removable(1) media
/* |___________ Drive # (0-1)
/* For the floppy drives, the major / minor assignment will be
/* +----------------+-----+---+-----+
/* +----------------+-----+---+-----+
/* | |_____ File system # ( 0-7 )
/* |____________ Drive # (0-3)
/****************************************************/
#define UDCUNIT(x) ((minor(x) & 0x18) >> 3)
long func
; /* Known to be 'read' */
register unit
= io
->i_unit
;
register timeout
, retries
, i
;
register int *memory
= (int *)(bn
*1024 + MEMDISK
);
cntaddr
= (char *)(udstd
[0] + VBIOBASE
); /* Booting from cntrlr 0 */
* prepare a command packet for the controller.
printf("UDC controller not ready, %x=%x\n",OB1
+cntaddr
,
udpkt
._pkdev
= UDCUNIT(unit
);
if (io
->i_ino
.i_dev
== 3) udpkt
._pkdev
+= 4; /* Floppy */
udpkt
._pkmem
[0] = (((long)io
->i_ma
) >> 16) & 0xffff;
udpkt
._pkmem
[1] = ((long)io
->i_ma
) & 0xffff;
udpkt
._psecno
= bn
* (DEV_BSIZE
/SECTSIZ
);
udpkt
._pkcnt
= (io
->i_cc
+ SECTSIZ
-1)/SECTSIZ
;
if (movep21(&udpkt
,cntaddr
+0x105,sizeof(udpkt
) )) {
cntaddr
[OB1
] = (char)0x80 ; /* signal packet transmitted */
cntaddr
[IB2
] = (char)0 ; /* clear ACK/NAK field */
cntaddr
[INT
] = (char)0x0 ; /* interrupt the controller */
printf ("Wrong command packet arrived at UDC\n");
printf ("Original UDC\n");
for (i
= 0; i
< sizeof(udpkt
); i
++ )
printf(" %0x\t%0x\n", ((char *)&udpkt
)[i
*2] & 0xff,
cntaddr
[0x105+i
*2] & 0xff);
* Wait until done (no interrupts now).
while (cntaddr
[IB2
] != (char)0x06 && cntaddr
[IB2
] != (char)0x15) {
printf("UDC controller timeout\n");
if (cntaddr
[IB2
] == (char)0x15) {
printf("Too many NAK from UDC - give up\n");
while (cntaddr
[IB1
] != (char)DEVRDY
)
/* DELAY (10000); /* Wait for his response */;
/* Ignore unsolicited status messages */
if (cntaddr
[PKID
] != (char)udpkt
._pkid
&& cntaddr
[PKSTT
] == (char)0x80)
cntaddr
[INT
] = (char)0x80;
if (cntaddr
[PKID
] != (char)udpkt
._pkid
||
cntaddr
[PKDEV
] != (char)udpkt
._pkdev
||
cntaddr
[PKLEN
] != (char)19 ||
cntaddr
[PKCMD
] != (char)udpkt
._pkcmd
||
cntaddr
[PKSTT
] != (char)0x70 || /* Command completion */
cntaddr
[STAT1
] != (char)0 ||
cntaddr
[STAT2
] != (char)0 ) {
printf ("Strange status from UDC:\n");
printf("Packet id=%x,unit=%x,original command=%x,status type=%x,status=%x\n",
(cntaddr
[STAT1
]*256+cntaddr
[STAT2
]) & 0xffff);
if (cntaddr
[PKLEN
] > 9) {
printf("More response info : ");
for (i
=1; i
<=cntaddr
[PKLEN
]-9; i
++)
printf("%x ", cntaddr
[STAT2
+2*i
] & 0xff);
cntaddr
[INT
] = (char)0x80;
cntaddr
[INT
] = (char)0x80;
mtpr(PADC
, 0); /* So data will come in right */
for (i
=0; i
<io
->i_cc
/4; i
++)
((int *)io
->i_buf
)[i
] = *memory
++;
while (udpkt
._pkfnc
!= 0x7f) ; /* wait for completion */
* Transfer a 21 bytes packet to the controller.
* the message is written to odd addresses, starting from
* For reliability, read it back and see if it's the same. If not,
register char *running_src
, *running_dest
;
register long running_cnt
;
for (; running_cnt
>0; running_cnt
--) {
*running_dest
++ = *running_src
++;
for (; running_cnt
>0; running_cnt
--) {
if (*running_dest
++ != *running_src
++) return(0);
* Just clean up any junk in the controller's response buffers.
cntaddr
= (char *)(udstd
[0] + VBIOBASE
); /* Booting from cntrlr 0 */
while (cntaddr
[IB1
] == (char)DEVRDY
) {
cntaddr
[OB2
] = (char)0x06; /* ACK */
cntaddr
[INT
] = (char)0; /* Force him to listen and to respond */