	.IF	LISTB
	.LIST
	.PAGE
	.ELSE
	.NOLIST
	.ENDC

;**********************************************************************
;
;	RAM Disk Routines
;
;	File:	SAGE.BIOSB.TEXT
;	Date:	 7-Nov-83
;	Issue:	2B
;
;
;	COPYRIGHT (c) 1982, 1983 SAGE Computer Technology
;	All Rights Reserved
;
;**********************************************************************
;
;	History:
;
;	1     13-Jun-82 Initial release.
;	1A     4-Sep-82 Added status readback for 130.
;	1B     2-Oct-82 Removed status readback for 130.
;	1C    14-Jan-83 Added CPM flag to make 128 byte blocks.
;	2     23-Mar-83 Initial SAGE IV release.
;	2A     2-Sep-83 Added 128 byte block control bit.
;			Put in check for RAMDisk above BIOSBASE.
;	2B     7-Nov-83 Return parameters for UNITSTATUS.
;
;**********************************************************************

;	Initialize & Status for RAM disk
STCHN11 CLR.W	(A1)
	TST.L	RDISKB		;Check if RAM Disk exists
	BEQ.S	$10		;No RAM Disk
	MOVE.L	RDISKT,D0	;Get Top of RAM Disk
	SUB.L	RDISKB,D0
	DIVU	#512.,D0	;Form number of blocks
	MOVE.W	#512.,2(A1)	;Bytes per sector = 512
	MOVE.W	#1,4(A1)	;Sectors per track = 1
	MOVE.W	D0,6(A1)	;Tracks per disk = number of blocks
	RTS

$10	MOVE.W	#-14.,2(A0)	;Return error code for no device
	RTS
	

INCHN11
	TST.L	RDISKB		;Check if RAM disk exists
	BNE	$10		;Have RAM disk
	MOVE.W	#-14,2(A0)	;Return error code for no device
$10	RTS

;	Write RAM Disk configuration
WCFCH11
	MOVE.L	(A1)+,RDISKB
	MOVE.L	(A1)+,RDISKT
	MOVE.W	(A1),RDISKF
	BSR.S	SSCHN11		;Perform System Startup on RAM Disk
	RTS
	
;	Read RAM Disk configuration
RCFCH11
	MOVE.L	RDISKB,(A1)+
	MOVE.L	RDISKT,(A1)+
	MOVE.W	RDISKF,(A1)
	RTS


;	System Startup of RAM Disk
SSCHN11
	TST.L	RDISKB
	BEQ.S	$30		;No RAM Disk defined
	TST.L	RDISKT
	BNE.S	$10		;Top end is not defaulted
	MOVE.L	BIOSBASE,RDISKT
$10	MOVE.L	RDISKT,D0
	CMP.L	RDISKB,D0
	BLE.S	$20		;Bottom is less than top
	CMP.L	BIOSBASE,D0
	BLE.S	$30		;BIOS is >= Top of RAMDisk
$20	CLR.L	RDISKB		;Disable RAMDisk
$30	RTS



;	Write to RAM disk
WTCHN11 MOVEM.L D1-D2/A1-A2,-(A7) ;Save working registers
	MOVEQ	#1,D2		;Set up write request code
	BRA.S	RWCHN11
	
RDCHN11 MOVEM.L D1-D2/A1-A2,-(A7) ;Save working registers
	CLR.B	D2

;	RAM disk transfer
RWCHN11 MOVE.L	RDISKB,D1	;Check if RAM disk is defined
	BEQ.S	$180		;RAM disk is not defined
	CLR.L	D0
	MOVE.W	12.(A0),D0	;Get starting block number
	LSL.L	#7,D0		;Convert into memory address
	BTST	#4,14.(A0)	;Check if 128 byte blocks (CP/M)
	BNE.S	$10		;Was 128 byte blocks
	LSL.L	#2,D0
$10	ADD.L	D1,D0
	MOVEA.L D0,A1		;Base of RAM disk block in memory
	
	MOVE.L	4(A0),D1	;Get length of transfer
	BEQ.S	$200		;No bytes to transfer
	ADD.L	D1,D0		;Form top address in RAM of transfer
	CMP.L	RDISKT,D0	;Check for RAM disk limit
	BGT.S	$190		;Transfer is too large
	BSR.S	MEMMOVE		;Move the memory
	BRA.S	$200
	
$180	MOVE.W	#-14.,2(A0)	;Set up code for bad device number
	BRA.S	$200

$190	MOVE.W	#-11.,2(A0)	;Set up illegal address reply code

$200	MOVEM.L (A7)+,D1-D2/A1-A2 ;Restore working registers
	RTS


;	Move the memory
MEMMOVE
	MOVEA.L 8(A0),A2	;Get memory address
	MOVE.L	A2,D0		;Check for even address
	LSR.B	#1,D0
	BCC.S	$100		;Is even address

;	Handle odd address transfer one byte at a time.
$10	SUBQ.L	#1,D1		;Adjust for DB instruction
	TST.B	D2		;Check direction
	BEQ.S	$40		;Was read direction
$20	MOVE.B	(A2)+,(A1)+
	DBF	D1,$20
$30	CLR.W	D1
	TST.L	D1		;Test for completion
	BNE.S	$10		;Not done yet
$35	RTS

$40	MOVE.B	(A1)+,(A2)+
	DBF	D1,$40
	BRA.S	$30		;Check for completion


;	Handle even address transfer in longer multiples
$100	MOVEQ	#3,D0
	AND.L	D1,D0		;Save least two bits
	LSR.L	#2,D1		;Form long word count
	BEQ.S	$135		;No long words to do
$110	SUBQ.L	#1,D1		;Adjust for DB instruction
	TST.B	D2		;Check direction
	BEQ.S	$140		;Was read direction

$120	MOVE.L	(A2)+,(A1)+
	DBF	D1,$120
$130	CLR.W	D1
	TST.L	D1		;Test for completion
	BNE.S	$110		;Not done yet
$135	MOVE.L	D0,D1		;Set up remaining count
	BEQ	$35		;Done
	BRA.S	$10		;Do remainder as single bytes

$140	MOVE.L	(A1)+,(A2)+
	DBF	D1,$140
	BRA.S	$130		;Check for completion


;	General Memory Access
WTCH130
	MOVEM.L D1-D2/A1-A2,-(A7) ;Save working registers
	MOVEQ	#1,D2		;Set up write request code
	BRA.S	RWCH130
	
RDCH130
	MOVEM.L D1-D2/A1-A2,-(A7)
	CLR.B	D2		;Set up read request code
	
RWCH130 MOVE.W	14.(A0),D0	;Form memory address
	SWAP	D0
	MOVE.W	12.(A0),D0
	MOVEA.L D0,A1
	MOVE.L	4(A0),D1	;Get length of transfer
	BEQ.S	$200		;No bytes to transfer
	BSR	MEMMOVE		;Move the memory
$200	MOVEM.L (A7)+,D1-D2/A1-A2
	RTS

                                                                                                                                                                                                                                                                                                                                                                                                                      