|
|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 11648 (0x2d80)
Types: TextFile
Names: »M320DSK.MAC«
└─⟦9f46c4107⟧ Bits:30005988 Sources for TurboDOS ver. 1.30 device drivers
└─⟦this⟧ »M320DSK.MAC«
.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»