|
DataMuseum.dkPresents historical artifacts from the history of: RegneCentralen RC850 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RegneCentralen RC850 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»