DataMuseum.dk

Presents historical artifacts from the history of:

RegneCentralen RC850

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about RegneCentralen RC850

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download

⟦0250211db⟧ TextFile

    Length: 11648 (0x2d80)
    Types: TextFile
    Names: »M320DSK.MAC«

Derivation

└─⟦9f46c4107⟧ Bits:30005988 Sources for TurboDOS ver. 1.30 device drivers
    └─⟦this⟧ »M320DSK.MAC« 

TextFile

.Z80
TITLE	DISK DRIVER FOR MEMOREX SERIES 32X DRIVES
SUBTTL	COPYRIGHT (c) by ASE GmbH, Altenstadt, vers.: 16.12.83
	NAME	('M320DR')
;
;*****************************************************************************
;
;	This driver supports the MEMOREX series 32x Winchesters with the
;	ASE SASI-Controller and the OMTI disk controller.
;
;*****************************************************************************
;
DRIVES  EQU   	1		;Number drives conected
NRETRY  EQU   	3		;Max number of retrys
FORMPT	EQU	0E5H		;FORMAT PATTERN
USERID	EQU	0		;USER ID (MAY BE CHANGED)
;
SECSIZ	EQU	512		;sector size
;
CBASEA	EQU	90H		;SASI Controller base address
RSTPRT	EQU	CBASEA		;SASI reset address
HSPRT	EQU	CBASEA+2	;SASI hardware status address
SELPRT	EQU	CBASEA+2	;SASI select port
CMDPRT	EQU	CBASEA+4	;SASI command port
DATPRT	EQU	CBASEA+4	;SASI data port
DCONT1	EQU	1		;SASI controller address
BUSY	EQU	3		;busy bit
MSG	EQU	5		;msg bit
CODAT	EQU	4		;control/data bit
REQ	EQU	0		;request bit
DIRSEL	EQU	2		;direction select bit
;
;	OMTI Controller commands
;
DINTLF	EQU	0		;interleave factor
DSENSS	EQU	0		;sense status
DRECAL	EQU	1		;recalibrate drive
DREQSE	EQU	3		;request sense
DFORMD	EQU	4		;format drive
DCHTRF	EQU	5		;check track format
DFORMT	EQU	6		;format track
DREADC	EQU	8		;read sector
DWRITC	EQU	0AH		;write sector
DSEEK	EQU	0BH		;seek
DASATR	EQU	0EH		;assign alternate track
DCOPY	EQU	20H		;copy sector
DASDP	EQU	0C2H		;assign disk parameters
;
	PAGE
;	HARDWARE INITIALIZATION
;
	COMMON	/?INIT?/
;
DSKIN@::OUT	(RSTPRT),A	;reset ALL controllers connected to the
	LD	B,0		;SASI controller
	DJNZ	$		;delay for controller setup
	DJNZ	$		;
	LD	HL,M320PA	;set drive parameters link pointer
	LD	(DRVPAR),HL	;
	XOR	A		;set LUN for drive 1
	LD	(ICOMNR+1),A	;
	CALL	INIDRV		;initialize removable drive
;
	LD	HL,640		;set number of 4096 byte blocks per surface
	LD	A,(NMBHD)	;get number of heads
	LD	B,H		;move HL to BC
	LD	C,L		;
INILP1:	ADD	HL,BC		;compute actual number of blocks
	DEC	A		;
	JR	NZ,INILP1	;
	LD	(NMBBLK),HL	;set number of blocks into drive table
	LD	A,(NMBHD)	;get number of heads
	SLA	A		;multiply number of heads by 4
	SLA	A		;
	LD	(NMDBLK),A	;set number of directory blocks
	LD	HL,320		;set number of tracks per surface
	LD	A,(NMBHD)	;get number of heads
	LD	B,H		;move HL to BC
	LD	C,L		;
INILOP:	ADD	HL,BC		;compute actual number of tracks
	DEC	A		;
	JR	NZ,INILOP	;
	LD	(NMBTRK),HL	;set number of tracks into drive table
	RET			;end of initialize
;
;
;
INIDRV:	LD	A,DCONT1	;now select the disk controller
	OUT	(SELPRT),A	;
	LD	B,0		;set loop counter
LOOP1:	IN	A,(HSPRT)	;and wait for BUSY, set by the disk controller
	BIT	BUSY,A		;
	JR	NZ,CONT		;continue if busy is set
	DEC	B		;decrement loop counter
	JR	NZ,LOOP1	;on count out, controller not present or
	RET			;not under power
CONT:	CALL	WATRE		;wait till controller is requesting the command
	LD	C,CMDPRT	;issue the assign disk parameters command
	LD	B,6		;command length
	LD	HL,ICOMNR	;
	OTIR			;
	CALL	WATRE		;wait till cont. is requesting the parameters
	LD	B,10		;parameters length
	LD	HL,(DRVPAR)	;get drive parameters pointer
	OTIR			;issue parameters to controller
	CALL	WATRE		;and wait for status read request
	IN	A,(CMDPRT)	;get status (not valid for this command)
	CALL	WATRE		;now wait for command acknowledge request
	IN	A,(CMDPRT)	;command acknowledge
	RET			;initialize done
;
WATRE:	IN	A,(HSPRT)	;wait till cont. is ready to talk
	BIT	REQ,A		;
	RET	NZ		;done if request set
	JR	WATRE		;else try again
;
ICOMNR:	DB	DASDP		;assign parameters command
	DB	0		;LUN
	DW	0		;
	DW	0		;
;
DRVPAR:	DW	0		;drive parameters link pointer
;
	PAGE
	CSEG
;
DSKDR@::LD	HL,MXLOCK	;SIGNAL TO OS, DRIVER IN USE
	CALL	WAIT##		;OR IF ALREADY IN USE, WAIT	
	XOR	A		;set driver busy LED
	OUT	(1),A		;
	CALL	FDECOD		;determine requested function
	PUSH	AF		;ON EXIT ENTRY SAVE RET CODE
	LD	HL,MXLOCK	;SIGNAL TO OS, DRIVER NOT LONGER
	CALL	SIGNAL##	;IN USE
	LD	A,1		;clear driver busy LED
	OUT	(1),A		;
	POP	AF		;RESTORE RETURN CODE
	RET			;DONE
;
FDECOD:	LD	A,(IX)		;GET FUNCTION CODE
	CP	0		;READ SECTOR(S)
	JP	Z,DREAD		;
	CP	1		;WRITE SECTOR(S)
	JP	Z,DWRITE	;
	CP	2		;DETERMINE DISK TYPE
	JP	Z,DTYPE		;
	CP	3		;SPECIFIC DISK READY
	JP	Z,DREADY	;
	CP	4		;FORMAT TRACK
	JP	Z,DFORMA	;
	LD	A,0FFH		;NONE OF THE ABOVE FUNCTIONS, 
	RET			;MUST BE WRONG CALL
;
;
;
DREAD:	LD	A,DREADC	;get read command
	JR	DREWR		;use common read-write code
;
DWRITE:	LD	A,DWRITC	;get write command
;
DREWR:	LD	(RQFUNC),A	;save command
				;the follwing routine computes the logical
				;address for the omti controller
	LD	L,(IX+2)	;get track low byte
	LD	H,(IX+3)	;and high byte
	LD	(RTRACK),HL	;save requested track number
	LD	B,H		;save track
	LD	C,L		;
	SLA	L		;now multiply the value by 17
	RL	H		;(number of sectors)
	SLA	L		;
	RL	H		;
	SLA	L		;
	RL	H		;
	SLA	L		;
	RL	H		;
	ADD	HL,BC		;
	LD	A,(IX+4)	;get requested sector number
	LD	(RSECT),A	;and save it for diagnostic purpose
	LD	C,A		;add starting sector number to logical
	LD	B,0		;address
	ADD	HL,BC		;
	LD	A,H		;store computed logical sector address
	LD	(LADDR1),A	;into command table
	LD	A,L		;
	LD	(LADDR0),A	;
	LD	A,(IX+1)	;get request drive number
	SLA	A		;shift drive number to bits 5 and 6
	SLA	A		;
	SLA	A		;
	SLA	A		;
	SLA	A		;
	LD	(LADDR2),A	;set LUN for drive access
;
	LD	A,(IX+6)	;GET SECTOR COUNT
	LD	(SECCNT),A	;SET SECTORS TO READ/WRITE
	LD	BC,SECSIZ	;get sector size
	LD	HL,0		;
DREWR1:	ADD	HL,BC		;transfer count = sector size x count
	DEC	A		;sector count = 0 ?
	JR	NZ,DREWR1	;
	LD	(MCOUNT),HL	;SAVE transfer count
	LD	H,(IX+11)	;GET DMA ADDRESS
	LD	L,(IX+10)	;
	LD	(DMAADR),HL	;SAVE DMA ADDRESS
	CALL	SETCMD		;issue read / write command
	CP	0FFH		;fatal error ?
	JR	Z,DREWR4	;if so, exit
DREWR2:	IN	A,(HSPRT)	;DATA REQUEST BIT SET ?
	BIT	CODAT,A		;if not, also an fatal error
	JR	NZ,DREWR4	;(may be write protected)
	LD	C,DATPRT	;get data port address
	LD	B,0		;and transfer count (0 = 256)
	LD	HL,(DMAADR)	;LOAD MEMORY ADDRESS
	LD	A,(RQFUNC)	;DECODE MOVE DIRECTION
	CP	DREADC		;
	JR	NZ,MOVWR	;
;	DI
	INIR			;read record
	INIR			;
;	EI
	JR	MOVCOM		;GO COMMON MOVE PART
MOVWR:	;DI
	OTIR			;write record
	OTIR			;
;	EI
MOVCOM:	EX	DE,HL		;SAVE DMA
	LD	HL,(MCOUNT)	;GET NUMBER BYTES TO MOVE
	LD	BC,SECSIZ	;SECTOR LENGTH
	XOR	A		;RESET CARRY BIT
	SBC	HL,BC		;SUBTRACT NUMBERS MOVED
	LD	(MCOUNT),HL	;RESTORE COUNT
	JR	Z,DREWR3	;ON ZERO RESULT ALL BYTES MOVED
	EX	DE,HL		;RESTORE DMA
	LD	(DMAADR),HL	;SAVE DMA ADDRESS
	CALL	WATREQ		;WAIT TILL NEXT SECTOR IS ready to transfer
	JR	DREWR2		;READ / write NEXT SECTOR
;
DREWR3:	CALL	RSTAT		;GET READ WRITE STATUS
	LD	A,(COMPST)	;get completion status
	AND	7		;only bit 0-2 are used (5+6 is LUN)
	OR	A		;
	LD	A,0FFH		;load error code
	RET	NZ		;if status not = 0, error
	XOR	A		;set good return code
	RET			;done
;
DREWR4:	CALL	RSTAT		;error exit for no DRQ
	LD	A,0FFH		;set error return
	RET			;done
;
;
;
DTYPE:	CALL	DREADY		;do ready test
	OR	A		;DRIVE READY ?
	RET	Z		;ON ZERO NOT READY
	LD	HL,HDSKST	;get drive table
DTYPE1:	LD	(IX+12),L	;SET DISK SPECIFICATION TABLE ADDR.
	LD	(IX+13),H	;
	LD	A,0FFH		;MEANS DRIVE READY
	RET			;DONE
;
;
;
DREADY:	LD	A,DSENSS	;get sense status command
	LD	(RQFUNC),A	;and set it into command table
	LD	HL,0		;clear logical address
	LD	(LADDR1),HL	;
	LD	(SECCNT),HL	;and number of sectors to read
	LD	A,(IX+1)	;get request drive number
	SLA	A		;shift drive number to bits 5 and 6
	SLA	A		;
	SLA	A		;
	SLA	A		;
	SLA	A		;
	LD	(LADDR2),A	;set LUN for drive access
	CALL	SETCMD		;issue command
	CP	0FFH		;fatal error ?
	JR	NZ,DREDY1	;
	XOR	A		;yes, set error
	RET			;exit
DREDY1:	CALL	RSTAT		;read status
	LD	A,(COMPST)	;get status
	AND	3		;mask out ready and error bit
	OR	A		;drive ready ?
	LD	A,0		;set error code
	RET	NZ		;error return on bad read status
	LD	A,0FFH		;set good return code
	RET			;done
;
;
;
DFORMA:	LD	A,(IX+1)	;get requested drive number
	SLA	A		;shift drive number to bits 5 and 6
	SLA	A		;
	SLA	A		;
	SLA	A		;
	SLA	A		;
	LD	(LADDR2),A	;set LUN
	LD	A,(IX+2)	;get requested track number
	OR	(IX+3)		;requested track = 0 ?
	JR	NZ,DFORM1	;if not, continue
	LD	A,DRECAL	;else recalibrate heads
	LD	(RQFUNC),A	;set command
	CALL	SETCMD		;issue command
	CP	0FFH		;fatal error detecded ?
	RET	Z		;if, leave driver
	CALL	RSTAT		;else get completition status
	OR	A		;test status
	LD	A,0FFH		;set error code
	RET	NZ		;on none zero, error
DFORM1:	LD	L,(IX+2)	;get track low byte
	LD	H,(IX+3)	;and high byte
	LD	B,H		;save track
	LD	C,L		;
	SLA	L		;now multiply the value by 17
	RL	H		;(number of sectors)
	SLA	L		;
	RL	H		;
	SLA	L		;
	RL	H		;
	SLA	L		;
	RL	H		;
	ADD	HL,BC		;
	LD	A,H		;set computed logical track address
	LD	(LADDR1),A	;into command table
	LD	A,L		;
	LD	(LADDR0),A	;
	LD	A,DFORMT	;get format track command
	LD	(RQFUNC),A	;set it to command table
	LD	A,DINTLF	;get interleave factor
	LD	(SECCNT),A	;set it also
	CALL	SETCMD		;issue command
	CALL	RSTAT		;get status
	RET			;done
;
	PAGE
;
;	the fallowing routine issues the command set into the
;	command table 
;
SETCMD:	IN	A,(HSPRT)	;test wether the controller is busy
	BIT	BUSY,A		;
	JR	Z,SETCM1	;everything ok
	LD	A,0FFH		;fatal error, busy set bevor command issued
	RET			;
SETCM1:	LD	A,DCONT1	;select the disk controller
	OUT	(SELPRT),A	;
	CALL	WATREQ		;and wait till controller is ready to talk
	LD	HL,DSKCMD	;get top of command table
	LD	C,CMDPRT	;get command port address
	LD	B,DSKCML	;set command length
	OTIR			;issue command
				;wait till controller is ready to talk
;
;
;
WATREQ:	IN	A,(HSPRT)	;wait till cont. is ready to talk
	BIT	REQ,A		;
	RET	NZ		;done if request set
	LD	HL,0		;pass over control
	CALL	DELAY##		;to OS
	JR	WATREQ		;and try again
;
;
;
RSTAT:	CALL	WATREQ		;wait till controler set request bit
RSTAT0:	IN	A,(CMDPRT)	;get status
	LD	B,A		;
	LD	(COMPST),A	;save completion status
	CALL	WATREQ		;wait for command complete request
	IN	A,(CMDPRT)	;
	LD	A,B		;restore status
	AND	1FH		;mask out LUN
	RET			;done
;
	PAGE
	DSEG
;	HARD DISKS SPECIFICATION TABLE
;       
HDSKST:	DB	5+80H	;BLOCK SIZE = 4096, fixed
NMBBLK:	DW	0	;number of blocks (set during initialization)
NMDBLK:	DB	0	;NUMBER OF DIRECTORY BLOKS (set during init.)
	DB	2	;SECTOR SIZE = 512
	DW	17	;SECTORS PER TRACK
NMBTRK:	DW	0	;TRACKS PER DISK (set during init.)
	DW	0	;RESERVED TRACKS
;
M320PA:	DB	5		;step pulse with 1 = 1 ys
	DB	1		;step period 1 = 50 ys
	DB	0		;bufferd step mode
NMBHD::	DB	5		;number of heads - 1
	DB	1		;cylinder high address
	DB	3FH		;cylinder low address -1
	DB	0		;reduced write current cylinder
	DB	0		;fixed, hard sectored
SECTRK:	DB	16		;sectors per track -1
	DB	0		;reserved
;
EVENT:	DW	0	;EVENT COUNTER FOR DISPATCHER
	DW	$	;
	DW	$-2	;
;
MXLOCK:	DW	1	;SIGNAL DISPATCHER DRIVER IN USE
	DW	$	;
	DW	$-2	;
;
;
;	HARD DISK COMMAND TABLE
;
DSKCMD:	
RQFUNC:	DB	0		;requested function code
LADDR2:	DB	0		;CURRENT LOGGED IN DISK
LADDR1:	DB	0		;logical address 1
LADDR0:	DB	0		;logical address 0
SECCNT:	DB	0		;number of sectors to read or write
CONTRF:	DB	0		;control field
DSKCML	EQU	$-DSKCMD
;
;	DISK STATUS TABLE
;
DSKST:
DSKSTL	EQU	$-DSKST
;
MCOUNT:	DW	0		;NUMBER OF BYTES TO MOVE
DMAADR:	DW	0		;DMA ADDRESS
RTRACK:	DW	0		;requested track number
RSECT:	DB	0		;
COMPST:	DB	0		;completion status
;
	END
«eof»