[net.micro.mac] MacSCSI and HFS

keashly@winston.UUCP (Lance Keashly) (01/10/86)

Well i'm one of those people that decided to make my own hard disk system for
my Mac. I went the route of the MacSCSI interface from Mr. Bass and hardware
wise it went fine. But software! What A Pain.

The code I got with the interface is pretty poor from the side of trying to
understand how the driver is made. The code that interfaces to the hardware
is OK. I could read it, understand it, and modify it. But the driver itself
is far from helpful, and if you want to make your MacSCSI work with HFS THIS
IS THE AREA of concern.

I understand that the original driver code is from the Aztec C distribution
so I thought I could find some more useful documentation. But NOOOO the
thing is written in this sparsly documented ASSEMBLY CODE (I bought a C
compiler package!) with no C code involved at all! I know C but assembler
takes longer.

Anyway to get the HFS working you need to worry about the control calls the
finder (5.0) will ask of the driver. Apple tech notes says somthing about it 
somewhere. The driver MUST RESPOND either do it, pretend to do it, or say it
can't. The open routine MUST ALSO SET THE DRIVER QUEUE ENTRY CORRECTLY. the
Driver as given doesn't even bother. Here's the way I've modified my driver,
look thru it and see what's helpful, I've done crude partitioning that works
and my drive is an ST225 (20 meg). The partioning is done by multiple
drivers that are compiled for different areas of the disk. To get the HFS
on the drive, once the thing is mounted on finder 5.0 with the HD20 stuff
ERASE THE DISK. If things go right it will make it into HFS disk. It does 
on mine.

Also, this stuff works great! The disk is as fast as the HYPER's plus I can
run MultiMac with a 10meg partition and finder 4.1 . This combination is GREAT,
I don't really have MultiMac (a bootlegged copy I use only to show what a Mac
can do) but when I find out where to get it I will.

THE CODE: Hacked from the John Bass release.

/*
 * MacSCSI partitioned driver routine.
 * This version was developed on the Mac under Aztec C.
 *
 */

#asm
;:ts=8
;
;
Start
	dc.w	$4f00		;locked, read, write, ctrl, status
	dc.w	0		;no delay
	dc.w	0		;no events
	dc.w	0		;no menu
	dc.w	open-Start	;open routine
	dc.w	rdwrt-Start	;prime routine
	dc.w	control-Start	;control routine
	dc.w	status-Start	;status routine
	dc.w	tst-Start	;close routine
	dc.b	6
	dc.b	".part1"	;name of driver
	ds	0		;for alignment
;
;
drvref	dc.w	0		;driver ref num
	dc.w	0		;file system ID
	dc.b	0		;sidedness of disk
	dc.b	0		;needs flush flag
	dc.w	0		;error count
;
diskbase_
	dc.l	0		;base of disk memory
;
openflg
	dc.w	0		;once only open flag
;
;
open
	movem.l	d0-d7/a0-a6,-(sp)	;save regs
	jsr		copen_
	movem.l	(sp)+,d0-d7/a0-a6	;restore regs
	lea	openflg,a0
	tst.w	(a0)
	bne	skip
	st	(a0)

; first, fix the drive queue

	move.l	#18,d0		;size of drive queue entry
	dc.w	$a51e		;NewPtr - system heap
	move.l	#$80000,(a0)+	; set the hidden flags (NO EJECT)
	clr.w	10(a0)		;local file system

	movem.l	d2-d7/a0-a6,-(sp)	;save regs
	jsr	get_DS_	;get the size of the drive
	move.l	d0,-(sp)
	jsr	get_DN_	;get the drive number
	move.l	(sp)+,d1
	movem.l	(sp)+,d2-d7/a0-a6	;restore regs

	move.w	d1,12(a0)	; HFS WANTS THE SIZE OF THE DRIVE IN BLOCKS
	move.w	d0,d7		;d7 has the drive number
	swap	d0
	move.w	24(a1),d0	;driver reference number
	lea	drvref,a2	;get address of driver reference number
	move.w	d0,(a2)		;set up status buffer
	dc.w	$a04e		;AddDriver

	move.l	(a1),-(sp)	;push handle to resource
	dc.w	$a992		;DetachResource

	link	a6,#-50
	move.l	sp,a0
	move.w	d7,22(a0)
	dc.w	$a00f		;DON"T KNOW WHAT THIS IS
	unlk	a6

skip
	move.l	#0,d0				;good return
	rts					;all done by INIT
;
rdwrt
	movem.l	d0-d7/a0-a6,-(sp)	;save regs
	jsr	ScsiRdWr_			;Call the C stuff
	movem.l	(sp)+,d0-d7/a0-a6	;restore regs
	move.l	#0,d0
	bra		tst			;exit via IOdone
;
control
	move.l	#-17,d0
	cmp.w	#1,26(a0)			;is it KillIO
	bne.s	next				;no, exit
	move.l	#0,d0				;okay return
	rts					;must respond this way
next
	cmp.w	#5,26(a0)	;either check or erase
	beq.s	ok		; lie and say we did it
	cmp.w	#6,26(a0)	;definitly format
	bne 	tst
	movem.l	d0-d7/a0-a6,-(sp)	;save regs
	jsr		cformat_	; do it if you want I don't
	movem.l	(sp)+,d0-d7/a0-a6	;restore regs
	move.l	#0,d0
ok
	move.l	#0,d0				;say we did it OK
	bra		tst
;
status
	move.l	#-18,d0		;we don't do status so say so
;
tst
	movem.l	d4-d7/a4-a6,-(sp)	;save regs going into IOdone
	move.l	$8fc,a0				;get IOdone address
	jsr	(a0)				;call IOdone
	movem.l	(sp)+,d4-d7/a4-a6	;restore them after IOdone
	rts				;and jump to it
;

		public	_Uend_,_Dorg_,_Cend_

save_
	lea	Start+(_Uend_-_Dorg_)+(_Cend_-Start),a4	; setup baseadr
	move.l	a0,Pbp_
	move.l	a1,Dp_				;save arguments
	rts

restore_
	move.l	Dp_,a1				; pass DCEptr
	rts
#endasm

#include	<memory.h>
#include	<resource.h>
#include	<desk.h>
#include	<pb.h>


/*
 * varibles used by asm routines
 * Dp and Pbp are device driver arguments handled by save/restore
 * ptr and dvrarg needed by AddDriver call
 */

DCEPtr		Dp;
ParmBlkPtr	Pbp;

/*
 * Local Stuff
 */

extern long DrvSize;
extern long FirstBlock;

/*
 * ScsiRdWr -- do a driver read/write function.
 */
ScsiRdWr() 
{
register struct ioParam *ip;
register long	len,part;
register short	blkno;
register char	*addr;

	save();

	ip = & Pbp->u.iop;
	part = Dp->dCtlPosition & 0xFFFFFE00;
	/* this does my partitioning */
	part = (part >> 9L) + FirstBlock;
	len = (ip->ioReqCount + 511) & 0xFFFFFE00;
	addr = ip->ioBuffer;
	while(len >= 512) {
		blkno = part;
		if((Pbp->ioTrap & 0xff) == 2) {
			ScsiRead(blkno, addr);
		 } else {
			ScsiWrite(blkno, addr);
		}
		len -= 512;
		addr += 512;
		part += 1;
	}
	ip->ioActCount = ip->ioReqCount;

	restore();					/* exit to I/O Done */
}

copen()
{
/* these are the c routines that are called on open */
	save();
	/* make sure the interface is reset, dangerous */
	ScsiReset();
	/* init the disk controller for the st225 */
	init_st();
	restore();
}

cformat()
{
/* these are the c routines that are called on format(initialize)*/
	save();
	/* do nothing right now */
	/* Scsifmt(); */
	restore();
}

long get_DS()
{
long x;
/* returns the size of the drive */
	save();
	x = DrvSize;
	restore();
	return(x);
}

int get_DN()
{
int x;
/* returns the drive number */
	save();
	x =  DRVNUM ;
	restore();
	return (x);
}
-- 
    Lance Keashly
    New Media Technologies Ltd.
    ..decvax!microsoft!ubc-vision!winston!keashly
    ..ihnp4!alberta!ubc-vision!winston!keashly

    #108 4664 Lougheed Highway
    Burnaby, B.C., Canada,
    V5C 5T5
    (604) 291-7111

rick@ut-ngp.UUCP (Rick Watson) (01/13/86)

Ok, here is a bit of my MacSCSI code. This will add a customizable icon
for your MacSCSI. A get info for the disk (and other places) will say
"SCSI" instead of "AppleTalk" for "Where".  Note that I use Megamax C, so
you may have to do some hacking to get back to Aztec C.  To re-customize
the icon you will have to create the icon, decompile it with REdit, and
edit the resulting hex back into the following code.

Rick Watson
University of Texas Computation Center
 arpa:   rick@ngp.UTEXAS.EDU   rick@ngp.ARPA
 uucp:   ...seismo!ut-sally!ut-ngp!rick   rick@ut-ngp.UUCP
 bitnet: ccaw001@utadnx
 phone:  512/471-3241

goes into np_drv.c:

/* io parameter block */

#define io_VRefNum	22	/* volume reference number */
#define io_CSCode	26	/* code */

#define io_csParam	28	/* cs parameters */
#define io_lun		28	/* 2 cs logical unit number */
#define io_sect		30	/* 2 cs sector number */
#define io_addr		32	/* 4 cs buffer address */
	
	.
	.  
	.

control:	
	cmpi.w	#21, io_CSCode(a0)
	beq.s	cntrl1				/* if Finder 4.1 get icon call */
	
	.
	.
	.
	
cntrl1:
	clr.l	d0
	move.l	a1, -(sp)
	lea	icnlst, a1				/* pass  icon list address */
	move.l	a1,  io_csParam(a0)
	move.l	(sp)+, a1
	bra	tst

	.
	.
	.
	
icnlst:
	dc.w	0x0000,0x0000,0x0000,0x0000,0x03FF,0xFFF8
	dc.w	0x0600,0x0018,0x0C00,0x0038,0x1800,0x0068
	dc.w	0x3000,0x00C8,0x6000,0x0188,0xC000,0x0308
	dc.w	0xFFFF,0xFE08,0xFFFF,0xFE08,0xC000,0x0608
	dc.w	0xC000,0x0608,0xC000,0x0608,0xC000,0x0608
	dc.w	0xC000,0x0608,0xC000,0x0608,0xC001,0xC608
	dc.w	0xC001,0xC608,0xC000,0x0608,0xC000,0x0608
	dc.w	0xC000,0x0618,0xC000,0x0630,0xC000,0x0660
	dc.w	0xC000,0x06C0,0xFFFF,0xFF80,0xFFFF,0xFE00
	dc.w	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
	dc.w	0x0000,0x0000,0x0000,0x0000

	dc.w	0x0000,0x0000,0x0000,0x0000,0x03FF,0xFFF8
	dc.w	0x07FF,0xFFF8,0x0FFF,0xFFF8,0x1FFF,0xFFF8
	dc.w	0x3FFF,0xFFF8,0x7FFF,0xFFF8,0xFFFF,0xFFF8
	dc.w	0xFFFF,0xFFF8,0xFFFF,0xFFF8,0xFFFF,0xFFF8
	dc.w	0xFFFF,0xFFF8,0xFFFF,0xFFF8,0xFFFF,0xFFF8
	dc.w	0xFFFF,0xFFF8,0xFFFF,0xFFF8,0xFFFF,0xFFF8
	dc.w	0xFFFF,0xFFF8,0xFFFF,0xFFF8,0xFFFF,0xFFF8
	dc.w	0xFFFF,0xFFF8,0xFFFF,0xFFF0,0xFFFF,0xFFE0
	dc.w	0xFFFF,0xFFC0,0xFFFF,0xFF80,0xFFFF,0xFE00
	dc.w	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
	dc.w	0x0000,0x0000,0x0000,0x0000
	dc.b	4				/* length of name */
	dc.b	"SCSI"				/* name */
	dc.b	0				/* alignment */

bass@dmsd.UUCP (John Bass) (02/05/86)

> Well i'm one of those people that decided to make my own hard disk system for
> my Mac. I went the route of the MacSCSI interface from Mr. Bass and hardware
> wise it went fine. But software! What A Pain.
> can do) but when I find out where to get it I will.

> 
> THE CODE: Hacked from the John Bass release.
> 
> /*
>  * MacSCSI partitioned driver routine.
>  * This version was developed on the Mac under Aztec C.
>  *
>  */
> 
> #asm

> /*
>  * ScsiRdWr -- do a driver read/write function.
>  */
> ScsiRdWr() 
> {
> register struct ioParam *ip;
> register long	len,part;
> register short	blkno;
> register char	*addr;
> 
> 	save();
> 
> 	ip = & Pbp->u.iop;
> 	part = Dp->dCtlPosition & 0xFFFFFE00;
> 	/* this does my partitioning */
> 	part = (part >> 9L) + FirstBlock;
> 	len = (ip->ioReqCount + 511) & 0xFFFFFE00;
> 	addr = ip->ioBuffer;
> 	while(len >= 512) {
> 		blkno = part;
> 		if((Pbp->ioTrap & 0xff) == 2) {
> 			ScsiRead(blkno, addr);
> 		 } else {
> 			ScsiWrite(blkno, addr);
> 		}
> 		len -= 512;
> 		addr += 512;
> 		part += 1;
> 	}
> 	ip->ioActCount = ip->ioReqCount;
> 
> 	restore();					/* exit to I/O Done */
> }

>     ..ihnp4!alberta!ubc-vision!winston!keashly
> 
>     #108 4664 Lougheed Highway
>     Burnaby, B.C., Canada,
>     V5C 5T5
>     (604) 291-7111

The above are segments from Lance Keashly's posting of our Copyrighted
MacSCSI np_dvr.c routine. While I support Lance's desire to share with
others -- his respect for others intellectual property is greatly lacking.
Lance violated the copyright in two ways:

	1) removing the copyright notice which SPECIFICALLY prohibits
	   making or maintaining ANY copies without the copyright notice
	   included.

	2) the removed copyright provided for unrestricted personal
	   non-comercial use --- any other reproduction requires
	   our written permission -- including posting to the net or
	   BBS's.

Copyrights are useful for protection of any written work from a few line
poem or jingle to a full length novel or programming system. We published
the MacSCSI article in DDJ to help the general hobbiest on a tight budget,
not to put others into our business -- thus the need to protect the copyright.
We depend on a much improved version of the software for part of our income.
It has been licensed at a nominal fee to several firms including the
Warp 9 which are now shipping their $895 internal drive via mail order.

Lastly Lance violated the rights of Manx in that the assembly language
segments were derived from the Aztec C Ram Disk -- we obtained their written
permission for publication in the Sept Doctor Dobbs issue and our use.

Thanks to Lance for his willingness to share, but please remove all copies
of the referenced article -- I have requested that Lance repost the article
with the proper copyright notices included.

Overall it is highly recommended to publish changes in a diff format with
minor context ... 

John Bass, MacSCSI author and copyright holder.