eject ;************************************************** ; HARDDISK Formatter ;************************************************** ;Autor Wilfried Schmitten, Heidebloeck 16, 2 Hamburg 74 ;letzte Aenderung : 29.10.1988 ;Include File fuer Harddisk Utility subttl Low Level Routines ; LOW LEVEL ROUTINES ; ------------------ dseg cyl: dw 0 sector: db 0 head: db 0 lun: db 0 ;0=Lun 0, 20=Lun 1 ;alternate Track ;acyl dw 0 ;ahead db 0 disretry equ 80h disecc equ 40h enbuffer equ 40h s10us equ 1 ilval equ 3 fillpattern equ 0e5h cseg delay: push bc ld b,0 ld c,a dly1: djnz dly1 dec c jr nz,dly1 pop bc ret ; Kommando an Controller ; Pointer 6 byte Kommando command: out (hd$select),a ;Controller mit dummy ansprechen ld b,6 ;6 byte ld c,hd$data ;nach Adresse coml: call waitreq ;teste Data request outi ;ausgeben jr nz,coml ret ; Kommando SET DRIVE CHARACTERISTICS ksetp: db 12,0,0,0,0,0 drive$data: if parkcyl > cylinder db high parkcyl db low parkcyl else db high cylinder db low cylinder endif db hd$head db high red$wrcur db low red$wrcur db high wr$pre$comp db low wr$pre$comp db 0 setp: ld a,(lun) ld (ksetp+1),a ld hl,ksetp call command ld hl,drive$data ld b,8 ld c,hd$data setl: call waitreq outi jr nz,setl jp errorcheck ; wie oben, aber exakte Einstellung der Cylinder-Zahl ; fuer formatieren und Drive Diagnostic fksetp: db 12,0,0,0,0,0 fdrive$data: db high cylinder db low cylinder db hd$head db high red$wrcur db low red$wrcur db high wr$pre$comp db low wr$pre$comp db 0 fsetp: ld a,(lun) ld (fksetp+1),a ld hl,fksetp call command ld hl,fdrive$data ld b,8 ld c,hd$data fsetl: call waitreq outi jr nz,fsetl jp errorcheck ; Kommando REQUEST SENSE kreqs: db 3,0,0,0,0,0 errorcheck: call waitreq in a,(hd$data) and 2 ret z ;fehlerfrei reqsense: ld a,1 call delay ld a,(lun) ld (kreqs+1),a ld hl,kreqs call command call waitreq and 2 jr nz,req1 ld hl,dsense ;Ergebnispuffer ld c,hd$data reql: ;4 byte data ini ;abholen req2: in a,(hd$status) rrca jr nc,req2 and 3 xor 1 ;0 fuer write, 1 fuer read jr z,reql ini ;Statusbyte abholen req1: scf ret dseg dsense ds 5 ; Command descriptor block cdbcom ds 1 ;Operation code cdbhead ds 1 ;bit 7 =cyl 2~10, head cdbsector ds 1 ;bit 7,6 = cyl 2~9,2~8, sector cdbcyl ds 1 ;cyl 2~7 - 2~0 cdbcount ds 1 ;block count cdbcontrol ds 1 ;bit 7=1=disable retrey ;bit 6=1=disable error correction ;bit 2,1,0 step option cseg waitreq: in a,(hd$status) rrca ret c jr waitreq ; Kommando CHECK DRIVE READY ; Ausgang nc = ready krcheck: db 0,0,0,0,0,0 readycheck: ld a,(lun) ld (krcheck+1),a ld hl,krcheck call command rc2: in a,(hd$status) rrca jr c,rc1 ;ready ld c,6 ld e,0feh ;conin Status call bdos or a scf jr nz,rc1 ;Abbruch jr rc2 ;weiter warten rc1: jp errorcheck ; Kommando RECALIBRATE kcalibr: db 1,0,0,0,0,s10us calibr: ld a,(lun) ld (kcalibr+1),a ld hl,kcalibr call command jp errorcheck ; Kommando CONTROLLER RAM DIAGNOSTIC kramdiag: db 0e0h,0,0,0,0,0 ramdiag: ld hl,kramdiag jr diag ; Kommando CONTROLLER INTERNAL DIAGNOSTIC kcontrdiag: db 0e4h,0,0,0,0,0 contrdiag: ld hl,kcontrdiag jr diag ; Kommando DRIVE DIAGNOSTIC kdrivediag: db 0e3h,0,0,0,0,disretry or s10us drivediag: ld a,(lun) ld (kdrivediag+1),a ld hl,kdrivediag diag: call command jp errorcheck ; Kommando READ ECC BURST ERROR LENGTH keccburst: db 0dh,0,0,0,0,0 dseg burstlength: ds 1 cseg eccburst: ld hl,keccburst call command ecc1: call waitreq and 1 jr z,ecc1 in a,(hd$data) ld (burstlength),a jp errorcheck ; Kommando WRITE DATA TO SECTOR BUFFER kfsector: db 15,0,0,0,1,0 fsector: ld hl,kfsector call command fs2: call waitreq and 2 ;wegen shift in waitreq jr nz,fs3 ld b,fillpattern ld c,hd$data fs5: out (c),b fs4: in a,(hd$status) rrca jr nc,fs4 and 3 xor 0 jr z,fs5 fs3: jp errorcheck ; Kommando FORMAT TRACK ftrack: ld a,6 jr form1 ; Kommando FORMAT BAD TRACK fbtrack: ld a,7 jr form1 ; Kommando ASSIGN ALTERNATE TRACK aatrack: ld a,11h form1: ld (cdbcom),a call cylcalc ld a,(interleave) ld (cdbcount),a ld a,enbuffer or s10us ld (cdbcontrol),a ld hl,cdbcom call command ld a,(cdbcom) cp 11h ;assign alternate track? jp nz,errorcheck call waitreq and 2 jp nz,errorcheck ld hl,alttrack ;alternate ;track Daten uebergeben ld c,hd$data form3: outi form2: in a,(hd$status) rrca jr nc,form2 and 3 xor 0 jr z,form3 jp errorcheck dseg alttrack: db 0,0,0,0 cseg ; Kommando READ ID readid: ld a,0e2h ld (cdbcom),a call cylcalc xor a ld (cdbcount),a ld a,disretry or s10us ld (cdbcontrol),a ld hl,cdbcom call command call waitreq and 2 jp nz,errorcheck ld hl,riddescrip ;ID Descriptor ;Daten lesen ld c,hd$data rid3: ini rid2: in a,(hd$status) rrca jr nc,rid2 and 3 xor 1 jr z,rid3 jp errorcheck dseg riddescrip: ds 4 cseg ; Kommando READ ; Eingang jeweils mit = controlbyte iniop equ 0a2h outiop equ 0a3h read: ld (cdbcontrol),a ld a,8 ld b,iniop ld c,1 jr rwcom ; Kommando WRITE write: ld (cdbcontrol),a ld a,10 ld b,outiop ld c,0 rwcom: ld (cdbcom),a ld a,b ld (rwpatch1+1),a ld a,c ld (rwpatch2+1),a call cylcalc ld a,1 ld (cdbcount),a ld hl,cdbcom call command call waitreq and 2 jr nz,rw2 ld hl,hddma ld c,hd$data rwpatch1: outi rw1: in a,(hd$status) rrca jr nc,rw1 and 3 rwpatch2: xor 0 ;0 fuer write, 1 fuer read jr z,rwpatch1 rw2: jp errorcheck dseg hddma: ds sector$size cseg ; Kommando FORMAT DRIVE ; Vorher Plattengroesse exakt einstellen!! ; Formatieren des Bereichs cylinder bis parkcyl ; fuehrt zu fehlerhaftem Verhalten kfdrive: db 4,0,0,0,0,enbuffer or s10us fdrive: ld a,(lun) ld (kfdrive+1),a ld a,(interleave) ld (kfdrive+4),a ld hl,kfdrive call command fdr1: in a,(hd$status) rrca jr c,fdr2 ;ready ld c,6 ld e,0feh ;conin Status call bdos or a scf jr z,fdr1 ; carry + = FF, dann ;Abbruch durch Reset ret fdr2: jp errorcheck ; !! Drive Parameter neu setzen ; Kommando SEEK seek: ld a,11 ld (cdbcom),a call cylcalc xor a ld (cdbcount),a ld a,disretry or s10us ld (cdbcontrol),a ld hl,cdbcom call command jp errorcheck ; Kommando READ VERIFY rdverify: ld a,5 ld (cdbcom),a call cylcalc ld a,sector$nmb ld (cdbcount),a ld a,disretry or disecc or s10us ld (cdbcontrol),a ld hl,cdbcom call command jp errorcheck cylcalc: ld a,(cyl) ld (cdbcyl),a ;low byte cylinder xor a ld a,(cyl+1) ld hl,sector rra rra rra push af ;2~10 in carry !! or (hl) ;2~9,2~8 lksbuendig + sector ld (cdbsector),a pop af rra and 80h ;2~10 inc hl or (hl) ;+ head ld hl,lun or (hl) ;+ lun ld (cdbhead),a ret