[net.micro.atari16] Public domain ramdisk

dyer@atari.UUcp (Landon Dyer) (03/11/86)

Here is a silly little ramdisk that is being placed in the
public domain.  Cut carefully at the dotted line, bring it
down to your ST, assemble it, link it, relmod it, and you're
on your way.  Install it by double-clicking it, or put it
in the \AUTO folder and forget about it.  It installs itself
as device M:.


- - - - - - - - - - - - cut here - - - - - - - - - - - - - - - - - - - - - -
* ramdisk.s

*------------------------------------------------------------------------
*									:
*	ST RAMDISK driver (M:)						:
*	Conditional assembly for 128K/512K Ramdisk			:
*									:
*	Public Domain (give it away, folks!)				:
*	This program, or any work derived from it, may not be sold	:
*	without permission from Atari Corp.				:
*									:
*----									:
*	Stick this program in the \AUTO folder of the boot volume.  Or,	:
*	you can simply double-click it after the desktop comes up.	:
*									:
*----									:
*  9-Aug-1985 lmd	Hacked it up					:
*  9-Jan-1986 lmd	Fixed sign-extension problem in _rw: and added	:
*			conditional assembly for two kinds of ramdisk.	:
*  9-Jan-1986 lmd	Make it "M:"					:
*									:
*------------------------------------------------------------------------


*+
*  Define one of the following to `1':
*
*-
_128k		equ	1		; 128K ramdisk
_512k		equ	0		; 512K ramdisk

 ifne _128k
ramdisk_size	equ	$20000		; size of 128K ramdisk
 endc
 ifne _512k
ramdisk_size	equ	$80000		; size of 512K ramdisk
 endc


*+
*  OS variables and vectors;
*  (stuff we have to subvert.)
*
*-
hdv_init	equ	$46a		; hdv_init()
hdv_bpb		equ	$472		; hdv_bpb(dev)
hdv_rw		equ	$476		; hdv_rw(rw, buf, count, recno, dev)
hdv_boot	equ	$47a		; hdv_boot()
hdv_mediach	equ	$47e		; hdv_mediach(dev)
_drvbits	equ	$4c2		; block device bitVector
_dskbufp	equ	$4c6		; pointer to common disk buffer


*+
*  Install driver;
*  setup ramdisk, then
*  terminate and stay resident.
*
*-
	move.l	4(sp),a4		; a4 -> our basepage
	lea	stack,a7		; new user stack
	clr.l	-(sp)			; get superuser mode
	move.w	#$20,-(sp)
	trap	#1
	addq	#6,sp
	move.l	d0,-(sp)		; save old SSP on stack

	bset.b	#4,_drvbits+2		; set bit for M:
	clr.l	a5			; easy zero-based pointer
	move.l	hdv_bpb(a5),o_bpb	; save old disk vectors
	move.l	hdv_rw(a5),o_rw
	move.l	hdv_mediach(a5),o_mediach
	move.l	#hbpb,hdv_bpb(a5)	; install ramdisk's vectors
	move.l	#hrw,hdv_rw(a5)
	move.l	#hmediach,hdv_mediach(a5)

	move.w	#$20,-(sp)		; back to user mode
	trap	#1			; (SSP already on the stack)
	addq	#6,sp

*--- clear first 8K of ramdisk:
	lea	ramdisk(pc),a0
	move.w	#$400-1,d0
clrit:	clr.l	(a0)+
	clr.l	(a0)+
	dbra	d0,clrit

*--- compute size of memory we want to keep:
	move.l	$c(a4),d3		; d3 = size of text
	add.l	$14(a4),d3		; d3 += size of data
	add.l	$1c(a4),d3		; d3 += size of bss
	add.l	#$0100,d3		; d3 += size of basepage
	add.l	#ramdisk_size,d3	; d3 += size of ramdisk

	pea	message(pc)		; print something informative
	move.w	#9,-(sp)
	trap	#1
	addq	#6,sp

*--- terminate and stay resident
	clr.w	-(sp)			; return code of zero
	move.l	d3,-(sp)		; # bytes to keep
	move.w	#$31,-(sp)		; Ptermres()
	trap	#1			; do it
	illegal				; "cannot happen"



*+
* LONG hbpb(dev) - return ptr to BPB (or NULL)
*
* Passed:	dev	4(sp).W
*
*-
hbpb:
	move.w	4(sp),d0		; d0 = devno
	move.l	o_bpb,a0		; a0 -> pass-through vector
	lea	_bpb(pc),a1		; a1 -> our handler
	bra	check_dev		; do it


*+
* LONG rw(rw, buf, count, recno, dev)
*
* Passed:	dev	$e(sp).W
*		recno	$c(sp).W
*		count	$a(sp).W
*		buf	6(sp).L
*		rw	4(sp).W
*
*-
hrw:
	move.w	$e(sp),d0		; d0 = devno
	move.l	o_rw,a0			; a0 -> pass-through vector
	lea	_rw(pc),a1		; a1 -> our handler
	bra	check_dev		; do it


*+
* LONG mediach(dev)
*
* Passed:	dev	4(sp).W
*
*-
hmediach:
	move.w	4(sp),d0		; d0 = devno
	move.l	o_mediach,a0		; a0 -> pass-through vector
	lea	_mediach(pc),a1	; a1 -> our handler


*+
* check_dev - use handler, or pass vector through
*
* Passed:	d0.w = device#
*		a0 ->  old handler
*		a1 ->  new handler
*		a5 ->  $0000 (zero-page ptr)
*
* Jumps-to:	(a1) if dev in range for this handler
*		(a0) otherwise
*
*-
check_dev:
	cmp.w	#12,d0			; M:?
	bne	chkd_f			; (no)
	move.l	a1,a0			; yes -- follow success vector
chkd_f:	jmp	(a0)			; do it



*+
* _bpb - return BPB for RAMDISK
*  Synopsis:	LONG _bpb(dev)
*		WORD dev;
*
*  Returns:	NULL, or a pointer to the BPB buffer
*
*-
_bpb:
	move.l	#thebpb,d0
	rts


*+
* _rw - read/write ramdisk sectors
*  Synopsis:	_rw(rw, buf, count, recno, dev)
*
*  Passed:	dev	$e(sp).W
*		recno	$c(sp).W
*		count	$a(sp).W
*		buf	6(sp).L
*		rw	4(sp).W
*
*-
_rw:
	lea	ramdisk(pc),a0		; a0 -> base of ramdisk
	moveq	#0,d0
	move.w	$c(sp),d0		; d0 = sect# << 9
	lsl.l	#8,d0
	lsl.l	#1,d0
	add.l	d0,a0			; a0 -> ramdisk mem

	moveq	#0,d2			; d2 = byte count / 32
	move.w	$a(sp),d2
	lsl.l	#4,d2			; log2(512 / 32) = 4

	move.l	6(sp),a1		; a1 -> buffer
	tst.w	4(sp)			; if (rw) exchange(a0, a1)
	beq	_rrw1
	exg	a0,a1			; swap src & dest

_rrw1:
_rrw2:	move.l	(a0)+,(a1)+		; move 32 bytes
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	subq.l	#1,d2			; while (--d2)
	bmi	_rrwq
	bne	_rrw2

_rrwq:	clr.l	d0			; return OK
	rts


*+
* _mediach - return FALSE media change (RAMDISK never changes)
* Synopsis:	_mediach(dev)
*		WORD dev;
*
* Returns:	0L
*
*-
_mediach:
	clr.l	d0
	rts


*+
*  BPB for ramdisk
*
*-
thebpb:
	dc.w	512			; #bytes/sector
	dc.w	2			; #sectors/cluster
	dc.w	1024			; #bytes/cluster
	dc.w	4			; rdlen (64 files)
	dc.w	2			; fat size
	dc.w	2			; 2nd FAT start
	dc.w	8			; 1st cluster start
 ifne _128k
	dc.w	124			; #clusters (128K)
 endc
 ifne _512k
	dc.w	508			; #clusters (512K)
 endc
	dc.w	1			; flags (16-bit FATs)



o_init:		dc.l	0		; old hdv_init
o_bpb:		dc.l	0		; old hdv_bpb
o_rw:		dc.l	0		; old hdv_rw
o_mediach:	dc.l	0		; old hdv_mediach

 ifne _128k
message:	dc.b	'128K'
 endc
 ifne _512k
message:	dc.b	'512K'
 endc
		dc.b	' RAMDISK installed as M:'
		dc.b	13,10
		dc.b	'version 9-Jan-1986 lmd.'
		dc.b	13,10
		dc.b	0

    even
ramdisk:	dc.w	0		; beginning of Ramdisk
stack		equ	ramdisk+ramdisk_size