Add SCSI MO device support.
Submitted by: Kawanobe Koh <kawanobe@st.rim.or.jp>
This commit is contained in:
parent
f0c093284d
commit
97a45538e4
@ -93,6 +93,26 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#ifndef CDBOOT
|
||||
|
||||
/*
|
||||
* PC-9801/PC-9821 SCSI MO booting
|
||||
* 2002/06/05-07/03 Kawanobe Koh <kawanobe@st.rim.or.jp>
|
||||
*
|
||||
*/
|
||||
scsi_hd:
|
||||
.code16
|
||||
push %cx
|
||||
push %ds
|
||||
mov %bl, %cl /* UA */
|
||||
and $0x0F, %cl
|
||||
xor %ax, %ax
|
||||
mov %ax, %ds
|
||||
mov (0x0482), %al /* SCSI HD equipment bits */
|
||||
shr %cl, %al
|
||||
pop %ds
|
||||
pop %cx
|
||||
test $1, %al
|
||||
ret
|
||||
|
||||
/*
|
||||
* biosread(dev, cyl, head, sec, nsec, offset)
|
||||
* Read "nsec" sectors from disk to offset "offset" in boot segment
|
||||
@ -118,54 +138,58 @@ ENTRY(biosread)
|
||||
push %esi
|
||||
push %edi
|
||||
|
||||
movb 0x14(%ebp), %dl /* sector */
|
||||
movb 0x10(%ebp), %dh /* head */
|
||||
movw 0x0c(%ebp), %cx /* cylinder */
|
||||
movb 0x08(%ebp), %al /* DA/UA */
|
||||
movb $0x06, %ah
|
||||
andb $0xf0, %al
|
||||
cmpb $0x30, %al
|
||||
jz fd
|
||||
cmpb $0x90, %al
|
||||
jnz 1f
|
||||
fd:
|
||||
incb %dl
|
||||
movb $0x02, %ch
|
||||
movb $0xd6, %ah
|
||||
1:
|
||||
movb 0x08(%ebp), %al
|
||||
movl %eax, %ebx
|
||||
mov 0x08(%ebp), %bl /* (byte) DA/UA */
|
||||
mov 0x0C(%ebp), %ecx /* (word) cylinder */
|
||||
mov 0x10(%ebp), %dh /* (byte) head */
|
||||
mov 0x14(%ebp), %dl /* (byte) sector */
|
||||
mov 0x18(%ebp), %esi /* (byte) number of sectors */
|
||||
mov 0x1C(%ebp), %edi /* (word) destination offset */
|
||||
|
||||
/* prot_to_real will set %es to BOOTSEG */
|
||||
call EXT(prot_to_real) /* enter real mode */
|
||||
mov %ebx, %eax
|
||||
xor %ebx, %ebx
|
||||
addr32
|
||||
movb 0x18(%ebp), %bl /* number of sectors */
|
||||
.code16
|
||||
shl $9, %ebx
|
||||
push %ebx
|
||||
.code32
|
||||
addr32
|
||||
data32
|
||||
mov 0x1c(%ebp), %ebx
|
||||
.code16
|
||||
mov %ebx, %ebp
|
||||
pop %ebx
|
||||
mov $0x06, %bh /* read data function */
|
||||
mov %bl, %al /* DA */
|
||||
and $0xF0, %al
|
||||
cmp $0x30, %al /* 1440KB FD */
|
||||
jz read_floppy
|
||||
cmp $0x90, %al /* 1200KB FD */
|
||||
jz read_floppy
|
||||
cmp $0xA0, %al /* SCSI HD or MO */
|
||||
jnz read_next
|
||||
call scsi_hd
|
||||
jnz read_next
|
||||
read_linear:
|
||||
mov %dh, %al /* change to linear sector */
|
||||
shl $5, %al /* multiply by 32 sector per track */
|
||||
add %dl, %al
|
||||
xor %dh, %dh /* higher 16 bits into %dx */
|
||||
mov %ch, %dl
|
||||
mov %cl, %ch /* lower 16 bits into %cx */
|
||||
mov %al, %cl
|
||||
and $0x7F, %bl /* linear access DA/UA */
|
||||
jmp read_next
|
||||
read_floppy:
|
||||
inc %dx /* sector address begins from one */
|
||||
mov $0x02, %ch /* 512 bytes sector */
|
||||
mov $0xD6, %bh /* MT MFM retry seek */
|
||||
read_next:
|
||||
mov %si, %ax /* number of sectors */
|
||||
shl $9, %ax /* multiply by 512 bytes */
|
||||
xchg %bx, %ax
|
||||
mov %di, %bp /* destination offset */
|
||||
int $0x1B /* disk bios call */
|
||||
jc read_end
|
||||
xor %ax, %ax
|
||||
read_end:
|
||||
mov %ax, %bx /* save return value */
|
||||
|
||||
int $0x1b
|
||||
jc 1f
|
||||
.code32
|
||||
xor %eax, %eax
|
||||
1:
|
||||
/* save return value (actually movw %ax, %bx) */
|
||||
mov %eax, %ebx
|
||||
|
||||
data32
|
||||
call EXT(real_to_prot) /* back to protected mode */
|
||||
|
||||
xor %eax, %eax
|
||||
movb %bh, %al /* return value in %ax */
|
||||
mov %bh, %al /* return value in %eax */
|
||||
|
||||
pop %edi
|
||||
pop %esi
|
||||
@ -360,46 +384,61 @@ ENTRY(get_diskinfo)
|
||||
push %ebp
|
||||
mov %esp, %ebp
|
||||
push %ebx
|
||||
push %esi
|
||||
push %edi
|
||||
|
||||
movb 0x8(%ebp), %dl /* diskinfo(drive #) */
|
||||
mov 0x08(%ebp), %bl /* (byte) DA/UA */
|
||||
|
||||
call EXT(prot_to_real) /* enter real mode */
|
||||
.code16
|
||||
mov %bl, %al /* DA */
|
||||
and $0xf0, %al
|
||||
mov $18, %dl /* 1440KB FD sectors per track */
|
||||
cmp $0x30, %al
|
||||
jz floppy
|
||||
mov $15, %dl /* 1200KB FD sectors per track */
|
||||
cmp $0x90, %al
|
||||
jz floppy
|
||||
cmp $0xA0, %al /* SCSI HD or MO */
|
||||
jnz sense
|
||||
call scsi_hd
|
||||
jnz sense
|
||||
|
||||
movb %dl, %al /* ask for disk info */
|
||||
andb $0xf0, %al
|
||||
cmpb $0x30, %al
|
||||
jz fdd4
|
||||
cmpb $0x90, %al
|
||||
jz fdd
|
||||
|
||||
movb %dl, %al
|
||||
movb $0x84, %ah
|
||||
push %ds /* SCSI MO or CD ? */
|
||||
xor %ax, %ax
|
||||
mov %ax, %ds
|
||||
and $0x0F, %bx /* UA */
|
||||
shl $2, %bx /* parameter offset */
|
||||
add $0x0460, %bx
|
||||
mov (%bx), %al /* SCSI equipment parameter[0] */
|
||||
and $0x1F, %al /* peripheral device type */
|
||||
cmp $7, %al /* SCSI MO */
|
||||
jnz good
|
||||
add $3, %bx
|
||||
mov (%bx), %al /* SCSI equipment parameter[3] */
|
||||
test $0x30, %al /* sector length from 256 to 2048 */
|
||||
jnz good
|
||||
or $0x10, %al /* forced set 512 bytes sector */
|
||||
mov %al, (%bx)
|
||||
mov $0xA100, %dx /* refered by C language */
|
||||
mov %dx, %ds
|
||||
mov %al, (%bx)
|
||||
good:
|
||||
pop %ds
|
||||
|
||||
mov $0xFFFE, %cx /* virtual 65535 cylinders setting */
|
||||
mov $0x0820, %dx /* standard 8 heads and 32 sectors */
|
||||
jmp ok
|
||||
sense:
|
||||
mov $0x84, %ah /* ask for disk info */
|
||||
mov %bl, %al
|
||||
int $0x1b
|
||||
|
||||
jnc ok
|
||||
jnc ok /* use %cx and %dx after */
|
||||
/*
|
||||
* Urk. Call failed. It is not supported for floppies by old BIOS's.
|
||||
* Guess it's a 15-sector floppy.
|
||||
*/
|
||||
fdd4:
|
||||
movb $18, %dl
|
||||
jmp 1f
|
||||
fdd:
|
||||
movb $15, %dl /* max sector */
|
||||
1:
|
||||
subb %ah, %ah /* %ax = 0 */
|
||||
movb %al, %al
|
||||
movb %ah, %bh /* %bh = 0 */
|
||||
movb $2, %bl /* %bl bits 0-3 = drive type,
|
||||
bit 2 = 1.2M */
|
||||
movb $79, %ch /* max track */
|
||||
movb $1, %cl /* # floppy drives installed */
|
||||
movb $2, %dh /* max head */
|
||||
/* es:di = parameter table */
|
||||
/* carry = 0 */
|
||||
floppy:
|
||||
mov $79, %cx /* 80 cylinders 1200K and 1440K FD */
|
||||
mov $2, %dh /* 2 heads as double side */
|
||||
ok:
|
||||
.code32
|
||||
data32
|
||||
@ -412,12 +451,9 @@ ok:
|
||||
* 8 bit sector
|
||||
*/
|
||||
mov %ecx, %eax
|
||||
sall $16,%eax /* << 16 */
|
||||
movb %dh, %ah /* max head */
|
||||
movb %dl, %al /* max sector (and # sectors) */
|
||||
sal $16, %eax /* max cylinder number from zero */
|
||||
mov %dx, %ax /* number of heads and sectors */
|
||||
|
||||
pop %edi
|
||||
pop %esi
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
@ -118,11 +118,16 @@ boot(int drive)
|
||||
dosdev = drive;
|
||||
#ifdef PC98
|
||||
maj = (drive&0x70) >> 3; /* a good first bet */
|
||||
if (maj == 4) { /* sd */
|
||||
if (maj == 4) { /* da */
|
||||
disk_equips = *(unsigned char *)V(0xA1482);
|
||||
unit = 0;
|
||||
for (i=0; i<(drive&0x0f); i++) {
|
||||
unit += (disk_equips >> i) & 1;
|
||||
int media = ((unsigned *)V(0xA1460))[i] & 0x1F;
|
||||
|
||||
if ((disk_equips >> i) & 1) /* HD */
|
||||
unit++;
|
||||
else if (media == 7) /* MO */
|
||||
unit++;
|
||||
}
|
||||
} else {
|
||||
unit = drive & 0x0f;
|
||||
|
@ -129,17 +129,6 @@ devopen(void)
|
||||
printf("bad disklabel\n");
|
||||
return 1;
|
||||
}
|
||||
if( (maj == 4) || (maj == 0) || (maj == 1))
|
||||
{
|
||||
if (dl->d_type == DTYPE_SCSI)
|
||||
{
|
||||
maj = 4; /* use scsi as boot dev */
|
||||
}
|
||||
else
|
||||
{
|
||||
maj = 0; /* must be ESDI/IDE */
|
||||
}
|
||||
}
|
||||
/* This little trick is for OnTrack DiskManager disks */
|
||||
boff = dl->d_partitions[part].p_offset -
|
||||
dl->d_partitions[2].p_offset + sector;
|
||||
|
@ -275,8 +275,8 @@ openrd(void)
|
||||
switch(maj)
|
||||
{
|
||||
#ifdef PC98
|
||||
case 4: /* sd */
|
||||
dosdev_copy = biosdrive | 0xa0;
|
||||
case 4: /* da */
|
||||
dosdev_copy = biosdrive | 0xA0; /* SCSI HD or MO */
|
||||
#else /* IBM-PC */
|
||||
case 0:
|
||||
case 4:
|
||||
@ -284,8 +284,8 @@ openrd(void)
|
||||
#endif
|
||||
break;
|
||||
#ifdef PC98
|
||||
case 0:
|
||||
case 2:
|
||||
case 0: /* wd */
|
||||
case 2: /* 1200KB fd */
|
||||
dosdev_copy = (maj << 3) | unit | 0x80;
|
||||
#else
|
||||
case 2:
|
||||
@ -293,7 +293,7 @@ openrd(void)
|
||||
#endif
|
||||
break;
|
||||
#ifdef PC98
|
||||
case 6:/* 1.44MB FD */
|
||||
case 6: /* 1440KB fd */
|
||||
dosdev_copy = (maj << 3) | unit;
|
||||
break;
|
||||
#endif
|
||||
|
@ -81,6 +81,9 @@ struct open_disk {
|
||||
#define BD_FLOPPY 0x0004
|
||||
#define BD_LABELOK 0x0008
|
||||
#define BD_PARTTABOK 0x0010
|
||||
#ifdef PC98
|
||||
#define BD_OPTICAL 0x0020
|
||||
#endif
|
||||
struct disklabel od_disklabel;
|
||||
int od_nslices; /* slice count */
|
||||
struct pc98_partition od_slicetab[MAX_SLICES];
|
||||
@ -198,7 +201,7 @@ bd_init(void)
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((unit & 0xa0) == 0xa0)
|
||||
if ((unit & 0xF0) == 0xA0) /* SCSI HD or MO */
|
||||
bdinfo[nbdinfo].bd_da_unit = da_drive++;
|
||||
}
|
||||
/* XXX we need "disk aliases" to make this simpler */
|
||||
@ -257,6 +260,14 @@ bd_int13probe(struct bdinfo *bd)
|
||||
bd->bd_flags |= BD_MODEINT13;
|
||||
return(1);
|
||||
}
|
||||
if ((bd->bd_unit & 0xF0) == 0xA0) {
|
||||
int media = ((unsigned *)PTOV(0xA1460))[bd->bd_unit & 0x0F] & 0x1F;
|
||||
|
||||
if (media == 7) { /* MO */
|
||||
bd->bd_flags |= BD_MODEINT13 | BD_OPTICAL;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
#else
|
||||
v86.ctl = V86_FLAGS;
|
||||
@ -1081,7 +1092,13 @@ bd_read(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest)
|
||||
v86.eax = 0x0600 | od->od_unit;
|
||||
v86.ecx = cyl;
|
||||
}
|
||||
v86.edx = (hd << 8) | sec;
|
||||
if (od->od_flags & BD_OPTICAL) {
|
||||
v86.eax &= 0xFF7F;
|
||||
v86.ecx = dblk & 0xFFFF;
|
||||
v86.edx = dblk >> 16;
|
||||
} else {
|
||||
v86.edx = (hd << 8) | sec;
|
||||
}
|
||||
v86.ebx = x * BIOSDISK_SECSIZE;
|
||||
v86.es = VTOPSEG(xp);
|
||||
v86.ebp = VTOPOFF(xp);
|
||||
@ -1362,6 +1379,10 @@ bd_getgeom(struct open_disk *od)
|
||||
od->od_cyl = 79;
|
||||
od->od_hds = 2;
|
||||
od->od_sec = (od->od_unit & 0xf0) == 0x30 ? 18 : 15;
|
||||
} else if (od->od_flags & BD_OPTICAL) {
|
||||
od->od_cyl = 0xFFFE;
|
||||
od->od_hds = 8;
|
||||
od->od_sec = 32;
|
||||
} else {
|
||||
v86.ctl = V86_FLAGS;
|
||||
v86.addr = 0x1b;
|
||||
@ -1423,19 +1444,26 @@ bd_getbigeom(int bunit)
|
||||
if (*(u_char *)PTOV(addr) & (1 << (unit & 0x0f)))
|
||||
if (hds++ == bunit)
|
||||
break;
|
||||
|
||||
if (unit >= 0xA0) {
|
||||
int media = ((unsigned *)PTOV(0xA1460))[unit & 0x0F] & 0x1F;
|
||||
|
||||
if (media == 7 && hds++ == bunit) /* SCSI MO */
|
||||
return(0xFFFE0820); /* C:65535 H:8 S:32 */
|
||||
}
|
||||
if (++unit == 0x84) {
|
||||
unit = 0xa0; /* SCSI HDD */
|
||||
unit = 0xA0; /* SCSI HDD */
|
||||
addr = 0xA1482;
|
||||
}
|
||||
}
|
||||
if (unit == 0xa7)
|
||||
return 0x4f010f;
|
||||
return 0x4F020F; /* 1200KB FD C:80 H:2 S:15 */
|
||||
v86.ctl = V86_FLAGS;
|
||||
v86.addr = 0x1b;
|
||||
v86.eax = 0x8400 | unit;
|
||||
v86int();
|
||||
if (v86.efl & 0x1)
|
||||
return 0x4f010f;
|
||||
return 0x4F020F; /* 1200KB FD C:80 H:2 S:15 */
|
||||
return ((v86.ecx & 0xffff) << 16) | (v86.edx & 0xffff);
|
||||
#else
|
||||
v86.ctl = V86_FLAGS;
|
||||
|
Loading…
Reference in New Issue
Block a user