	title	'Program to PARK heads of hard disks'


;**********************************************************
;	Before using this program you must customize
;	it for the Winchester Drive(s) that you are using.
;	Failure to do this could cause damage to your hard disk.
;	Not all hard drives have a dedicated shipping zone
;	for parking the heads.  If your drive does not then
;	simply wait till the select light goes out and turn your
;	machine off,  there is no benefit in running this program.
;	Of the three drives that are available from Plu*Perfect
;	Systems for use with the Advent TurboROM, two do have such
;	shipping zones but this is atypical.
;		Shugart 604	has shipping zone at cylinder 180
;		Rodime	252	has no landing zone and it is
;				imposible to seek beyond cyl 305
;		Seagate	225	has shipping zone from cyl 615-670
;
;
;	Use your text editor (WordStar in non-doc mode or Perfect Writer)
;	to edit the equates below to match your situation.
;
;	Then assemble it using ASM which is supplied with
;	your CP/M system.
;
;	"ASM TURBOSAF<CR>"
;
;(this takes the file TURBOSAF.ASM and generates a file TURBOSAF.HEX)
;
;	Generate a COM file with LOAD which was also supplied with
;	your CP/M system.
;
;	"LOAD TURBOSAF<CR>"
;
;(this takes the file TURBOSAF.HEX and generates a file TURBOSAF.COM)
;
;	You can now run TURBOSAF before shutting down your machine.
;********************************************************************
;appropriate zones are
; ST225		=	650
; RO252		=	305		;doesn't do anything
; SA604		=	180
;**********************************************************************

CLRSCR		equ	01AH		;clear Kaypro screen
CR		equ	00DH		;carriage return
LF		equ	00AH		;line feed

PRINT$STR	equ	9		;CP/M string printer
BDOS		equ	0005		;standard BDOS entry point

SHIP$ZONE$1	equ	650		;set for Seagate ST225
SHIP$ZONE$2	equ	0		;no second drive

STEP$RATE$1	equ	0		;almost all moderen drives can do
					;buffered seek.
STEP$RATE$2	equ	0


;controller ports
HBASE		equ	080H		;base address

HSDH		equ	HBASE+6		;head, drive register
HSTATUS		equ	HBASE+7		;status register
HCOMMAND	equ	HBASE+7		;command register
HCYLLO		equ	HBASE+4		;low byte cylinder
HCYLHI		equ	HBASE+5		;high byte cylinder

;**************************************************************
	ORG	100H		;standard runtime address

	jmp	start		;jump around parameters

maxcyl1:
	dw	SHIP$ZONE$1	;patchable location for drive 1
	db	step$rate$1	;step rate for drive
				;0 is buffered seek

	db	CR,LF,LF
	db	'The heads of Physical Drive 1'
	db	' are positioned over the Safety Zone$'

maxcyl2:
	dw	SHIP$ZONE$2	;patchable location for drive 2
	db	step$rate$2	;step rate for drive
				;0 is buffered seek

	db	CR,LF,LF
	db	'The heads of Physical Drive 2'
	db	' are positioned over the Safety Zone$'


sign$on:
	db	CLRSCR
	db	'TURBOSAF  Copyright (c) 1986 Plu*Perfect Systems'
	db	CR,LF,'$'


desel$msg:
 db CR,LF,LF
 db 'All Hard Drives are now deselected and it is safe',CR,LF
 db 'to turn the power off and move your computer$',CR,LF

start:	lxi	sp,stack	;set up our own stack
	lxi	d,sign$on
	mvi	c,PRINT$STR
	call	BDOS


	mvi	a,00001000B		;drive one head zero
	out	HSDH
	lxi	h,maxcyl1			;see if drive 1 to be secured
	mov	e,m
	inx	h
	mov	a,m
	ora	e
	cnz	do$safe

	mvi	a,00010000B		;drive two head zero
	out	HSDH
	lxi	h,maxcyl2
	mov	e,m
	inx	h
	mov	a,m
	ora	e
	cnz	do$safe

;*******************************************************************
;now select controller drive 0 so that all drives are deselected

deselect:
	in	HSTATUS			;wait till controller not busy
	rlc
	jc	deselect

	xra	a
	out	HSDH			;select drive zero
	lxi	d,desel$msg
	mvi	c,PRINT$STR
	call	BDOS			;tell people we are finished
	di				;make sure we stay hung
self:	jmp	self			;hang the machine



;*******************************************************
;actual safety routine
do$safe:
	push	psw
busy:	in	HSTATUS			;wait till controller
	rlc
	jc	busy
	pop	psw
;now select drive one and seek safety zone
	out	HCYLHI			;high order cylinder
	mov	a,e
	out	HCYLLO			;low order cylinder
	inx	h
	mov	a,m
	ori	01110000B		;compute seek command
	out	HCOMMAND		;issue seek but don't wait
	inx	h
	xchg
	mvi	c,PRINT$STR
	call	BDOS
	ret


	ds	64
stack	equ	$
	end
	cnz	do$safe

	mvi	a,00010000B		;drive two head zero
	out	HSDH
	lxi	h,maxcyl2
	mov	e,m
	inx	h
	mov	a,m
	ora