page ;************************************************** ; HARDDISK Formatter ;************************************************** ;Autor Wilfried Schmitten, Heidebloeck 16, 2 Hamburg 74 ;letzte Aenderung : 17.2.1989 ;Include File fuer Harddisk Utility subttl HD Funktionen ; HARDDISK FUNKTIONEN ; ------------------- tstart db 'Test beginnt ',0dh,0ah,0 tend db 'Test beendet ',0dh,0ah,0 trdiag db 'Controller Ram Diagnostic',0dh,0ah,0 tidiag db 'Controller Internal Diagnostic',0dh,0ah,0 tcdiag db 'Check Drive Ready',0dh,0ah,0 tfstart db 'Funktion beginnt ',0dh,0ah,0 tfend db 'Funktion beendet ',0dh,0ah,0 ; Kommando CONTROLLER DIAGNOSTIC sramdiag: ld a,(Fnr) call wselect call cursorhome call erasescreenend ld hl,tstart call epstr ld hl,trdiag call epstr call ramdiag jr nc,srd1 call sumerror srd1: ld hl,tend call epstr call cursordown ld hl,tstart call epstr ld hl,tidiag call epstr call contrdiag jr nc,srd2 call sumerror srd2: ld hl,tend call epstr call cursordown ld hl,tstart call epstr ld hl,tcdiag call epstr call readycheck jr nc,srd3 call sumerror srd3: ld hl,tend call epstr call wjn ret ; Kommando FORMAT DRIVE tform: db 'Formatieren der gesamten Platte',0dh,0ah db 'Interleave Factor ' tfil: db 0,0,0 db 0dh,0ah db 'Muster ' tfpat: db 0,0 db 0dh,0ah db 0 tfbrk: db 'Funktion abgebrochen ',0dh,0ah,0 format: ld a,(Jnr) call wselect call cursorhome call erasescreenend ld hl,tfstart call epstr ld a,(interleave) ld de,tfil call madc ld a,fillpattern ld de,tfpat call ma2hc ld hl,tform call epstr call fsetp ;exakte Drive Parameter setzen call c,sumerror ld a,1 call delay call fsector call c,sumerror if test ld a,40h ;Fehler Code ld (dsense),a ;Software Error scf else call fdrive endif jr nc,formt1 ;fehlerfrei cp 0ffh jr nz,formt2 ;Fehler ld c,6 ld e,0fdh call bdos ;User Abbruch, Zeichen holen ld hl,tfbrk call epstr out (hd$reset),a xor a out (hd$mask),a ld a,1 call delay ;?? jr formt1 formt2: call sumerror formt1: call setp ;drive Par. incl Parkcyl call c,sumerror call newline ld hl,tfend call epstr call wjn ret ; Kommando PARKSPUR ANFAHREN tkpark: db 'Parkcylinder ' tkcyl db 0,0,0,0,0 db ' wird angefahren',0dh,0ah,0 kpark: ld a,(Fnr) call wselect call cursorhome call erasescreenend ld hl,tfstart call epstr ld hl,parkcyl ld de,tkcyl call mhldc ld hl,tkpark call epstr ld hl,parkcyl-1 ld (cyl),hl xor a ld (sector),a ld (head),a call seek call c,sumerror call newline ld hl,tfend call epstr call wjn ret ; Kommando FORMAT CYLINDER fscyl: ld a,(Hnr) call wselect call cursorhome call erasescreenend ld hl,tfstart call epstr call fsector ld hl,(scyl) ;Startwerte ld (cyl),hl ld a,(shead) ld (head),a xor a ld (sector),a fsc1: call factiv if test ld a,40h ld (dsense),a ;Fehlercode scf ;SW Error else call ftrack endif call c,sumerror call newline ld hl,tfend call epstr call wjn ret factiv: ld a,(head) ld de,fhead call madc ld hl,(cyl) ld de,fcyl call mhldc ld a,(lun) or a jr z,fact1 ld a,1 fact1: ld de,flun call madc ld hl,ftext call epstr ret ftext: db 0dh db 'Formatting on Unit ' flun: db 0,0,0 db ' Cylinder ' fcyl: db 0,0,0,0,0 db ' Head ' fhead: db 0,0,0 db 0 ;terminator ; Kommando VERIFY DRIVE tverdr: db ' Verify Drive',0dh,0ah,0 verdr: ld a,(Fnr) call wselect call cursorhome call erasescreenend ld hl,tstart call epstr ld hl,tverdr call epstr ld hl,(scyl) ;Startwerte ld (cyl),hl ld a,(shead) ld (head),a xor a ld (sector),a vdr1: call vactiv jr nc,vdr4 call newline ld hl,tfbrk call epstr jp vdr5 ;Abbruch vdr4: call rdverify jr nc,vdr3 ;fehlerfrei call c,sumerror ld a,hd$head-1 ;bei Fehler letzten Kopf einstellen ld (head),a vdr3: ld hl,head ;Head weiterschalten inc (hl) vdr2: ld hl,(cyl) ;mit Vorgaben vergleichen ld de,(ecyl) xor a sbc hl,de jr c,vdrnorm ;weiter ld a,(ehead) ld b,a ld a,(head) cp b jr c,vdrnorm ;weiter jr z,vdrnorm vdr5: call newline ld hl,tend call epstr call wjn ret ;Vorgabe erreicht, Ende vdrnorm: ld hl,head ;Head weiterschalten ld a,hd$head sub (hl) jr nz,vdr1 ;weiter, head 0....hd$head-1 ld (hl),a ld hl,(cyl) ;Cylinder weiterschalten inc hl ld (cyl),hl jr vdr1 vactiv: ld a,(head) ld de,vhead call madc ld hl,(cyl) ld de,vcyl call mhldc ld a,(lun) or a jr z,vact1 ld a,1 vact1: ld de,vlun call madc ld hl,vtext call epstr ; call usrbreak ; ret usrbreak: ld c,6 ;Console abfragen ld e,0feh call bdos or a ret z ld c,6 ;Zeichen abholen ld e,0fdh call bdos scf ret vtext: db 0dh db 'Verifying Unit ' vlun: db 0,0,0 db ' Cylinder ' vcyl: db 0,0,0,0,0 db ' Head ' vhead: db 0,0,0 db 0 ;terminator ;Schreib/Lesetest der Platte rwtest: ld a,(Hnr) call wselect call cursorhome call erasescreenend ld hl,tfstart call epstr ld a,(lun) or a jr z,rwa1 ld a,1 rwa1: ld de,rwalun call madc ld hl,rwatext call epstr ld hl,(scyl) ;Startwerte uebernehmen ld (cyl),hl ld a,(ssector) ld (sector),a ld a,(shead) ld (head),a rwt1: call rwactiv jr nc,rwt4 call newline ld hl,tfbrk call epstr jr rwt5 ;Abbruch rwt4: call rwcheck jr nc,rwt3 ;fehlerfrei call newline ;Fehler bei write ld hl,tfend call epstr call wjn ;bei ECC Error wird Pruefung ret ;in rwcheck fortgesetzt rwt3: ld hl,sector ;Sektor weiterschalten inc (hl) rwt2: ld hl,(cyl) ;mit Vorgaben vergleichen ld de,(ecyl) xor a sbc hl,de jr c,rwtnorm ;weiter ld a,(ehead) ld b,a ld a,(head) cp b jr c,rwtnorm ;weiter ld a,(esector) ld b,a ld a,(sector) cp b jr c,rwtnorm ;weiter jr z,rwtnorm rwt5: call newline ld hl,tfend call epstr call wjn or a ret ;Vorgabe erreicht, Ende rwtnorm: ld hl,sector ld a,sector$nmb sub (hl) jr nz,rwt1 ;weiter, sector 0....sector$nmb-1 ld (hl),a ld hl,head ;Head weiterschalten inc (hl) ld a,hd$head sub (hl) jr nz,rwt1 ;weiter, head 0....hd$head-1 ld (hl),a ld hl,(cyl) ;Cylinder weiterschalten inc hl ld (cyl),hl jr rwt1 rwcheck: ld a,(wdhlg) ld b,a ;Anzahl Wiederholungen rwc1: push bc call mpattern ld a,disretry or s10us if test ld a,40h ld (dsense),a scf else call write endif jr nc,rwc3 ;fehlerfrei call sumerror ex (sp),hl ;Rwcheck abbrechen ld h,1 ;indem Wiederholungszaehler ex (sp),hl ;normiert wird scf jr rwc5 rwc3: ld a,disretry or disecc or s10us call read jr nc,rwc4 ;fehlerfrei call sumerror ;carry Fehler ex (sp),hl ld h,1 ;Wiederholungszaehler normieren ex (sp),hl ;um rwcheck abzubrechen ld a,sector$nmb-1 ;letzten Sector einstellen ld (sector),a ;um auf naechsten track zu schalten ;falls es sich um ECC Fehler handelt ;soll die Pruefung fortgesetzt ;werden ld a,(dsense) and 3fh cp 11h ;Uncorrectable ECC Error jr z,rwc6 cp 18h ;Correctable ECC Error scf jr nz,rwc5 ;sonst Ausgang rwc6: call eccburst ;ECC Burst Error Length lesen ld a,(burstlength) ld de,tburstlength call madc ld hl,tberror call epstr rwc4: or a rwc5: pop bc djnz rwc1 ret tberror: db 0dh,0ah db 'ECC Burst Error Length ' tburstlength: db 0,0,0 db 0dh,0ah db 0 ;Testmuster erzeugen mpattern: push bc ld hl,(tpattern1) ; > , > flags push hl ld bc,sector$size ld hl,hddma mp1: pop af ld (hl),a inc hl dec bc rla push af ld a,b or c jr nz,mp1 ld hl,(tpattern2) ld (tpattern1),hl pop hl ld (tpattern2),hl pop bc ret tpattern1: dw 0100h tpattern2: dw 0fe00h rwactiv: ld a,(head) ld de,rwahead call madc ld hl,(cyl) ld de,rwacyl call mhldc ld a,(sector) ld de,rwasector call madc ld hl,rwatext1 call epstr call usrbreak ;Tastenabfrage ret rwatext: db 0dh db 'R/W Test Unit ' rwalun: db 0,0,0,0dh,0ah,0 rwatext1: db 0dh db ' Cylinder ' rwacyl: db 0,0,0,0,0 db ' Head ' rwahead: db 0,0,0 db ' Sector ' rwasector: db 0,0,0 db 0 ;terminator ; Kommando DRIVE DIAGNOSTIC tdrdiag: db ' Drive Diagnostic',0dh,0ah,0 drdiag: ld a,(Fnr) call wselect call cursorhome call erasescreenend ld hl,tstart call epstr ld hl,tdrdiag call epstr call fsetp call c,sumerror call drivediag call c,sumerror call setp call c,sumerror ld hl,tend call epstr call wjn ret ; Kommando DRIVE READ ID tdrrdi: db ' Drive Read Ident',0dh,0ah,0 drrdid: ld a,(Fnr) call wselect call cursorhome call erasescreenend ld hl,tstart call epstr ld hl,tdrrdi call epstr ld hl,(scyl) ;Startwerte ld (cyl),hl ld a,(shead) ld (head),a xor a ld (sector),a drr1: call readid call c,sumerror drr3: call drractiv ld hl,head ;Head weiterschalten inc (hl) drr2: ld hl,(cyl) ;mit Vorgaben vergleichen ld de,(ecyl) xor a sbc hl,de jr c,drrnorm ;weiter ld a,(ehead) ld b,a ld a,(head) cp b jr c,drrnorm ;weiter jr z,drrnorm call newline ld hl,tend call epstr call wjn or a ret ;Vorgabe erreicht, Ende drrnorm: ld hl,head ;Head weiterschalten ld a,hd$head sub (hl) jr nz,drr1 ;weiter, head 0....hd$head-1 ld (hl),a ld hl,(cyl) ;Cylinder weiterschalten inc hl ld (cyl),hl jr drr1 drractiv: ld a,(riddescrip+2) and 0fh ld de,drrhead call madc ld hl,(riddescrip) ld a,h ld h,l ld l,a ld de,drrcyl call mhldc ld hl,drrtext call epstr ld a,(riddescrip+2) and 0e0h jr z,drra1 ld hl,drrflags ld b,3 drra3: push bc rlca call stext jr nc,drra2 push af push hl call epstr pop hl pop af drra2: pop bc djnz drra3 drra1: ld c,6 ;Console abfragen ld e,0feh call bdos or a ret z scf ret drrtext: db 0dh db 'Reading Ident Cylinder ' drrcyl: db 0,0,0,0,0 db ' Head ' drrhead:db 0,0,0 db 0 ;terminator drrflags: db 0 db 0dh,0ah,'Bad Track',0 db 0dh,0ah,'Bad Track with Alternate Assigned',0 db 0dh,0ah,'Alternate Track',0 ;----------------------- ; Kommando ASSIGN ALTERNATE TRACKS fsalt: ld a,(Jnr) call wselect call cursorhome call erasescreenend ld a,(lun) or a jr z,aac1 ld a,1 aac1: ld de,tfalun call madc ld hl,txfalt call epstr ld hl,tfstart call epstr ld a,(deflinto) ;Anzahl in Defect List or a ld hl,tfsnodat jr z,fsa5 ;keine Daten da ld b,a ld a,(altlinto) ;Anzahl Alternate Daten cp b ld hl,tfsnoalt jr c,fsa5 ;?? zu wenig Alternate Daten ld hl,deflist ;pointer def list ld de,altlist ;pointer altlist fsa3: push bc push de push hl ex de,hl ;alternate data push hl ld a,(hl) ;low byte alt cyl ld (alttrack+2),a xor a ; 0, clear carry ld (alttrack+3),a ;4. byte 0 inc hl ld a,(hl) ;high byte alt cyl rra rra rra ;bit 8 und 9 lksbuendig ld (alttrack+1),a ;bit 10 in carry rra and 80h ;bit 10 lksbuendig inc hl or (hl) ;alt head dazu ld (alttrack),a ex de,hl ; pointer defect ld e,(hl) ;low byte def cyl inc hl ld d,(hl) ;high byte def cyl inc hl ld (cyl),de ld a,(hl) ;def head ld (head),a xor a ld (sector),a ;sector 0 ;den Rest macht Funktionsaufruf pop hl ;wieder Pointer alternate Data call aactiv if test ld a,40h ld (dsense),a ;Fehlercode scf ;SW Error else call aatrack endif jr nc,fsa2 call newline call sumerror ld hl,tfbrk call epstr pop hl pop de pop bc ld b,1 jr fsa1 fsa2: pop hl pop de ld bc,4 ;naechster Datensatz add hl,bc ex de,hl add hl,bc ex de,hl pop bc djnz fsa3 fsa1: call newline ld hl,tfend fsa5: call epstr call wjn ret aactiv: ld e,(hl) ;alternate data inc hl ld d,(hl) ;Cylinder inc hl ld a,(hl) ;head push de ld de,tfahd call madc pop hl ld de,tfacyl call mhldc ld a,(head) ld de,tfdhd call madc ld hl,(cyl) ld de,tfdcyl call mhldc ld hl,tfalttxt call epstr ret tfsnodat: db 0dh,0ah,'Keine Defect List',0dh,0ah,0 tfsnoalt: db 0dh,0ah,'Zu wenig alternate Tracks',0dh,0ah,0 txfalt: db 'Zuweisung Alternate Track Unit ' tfalun: db 0,0,0 db 0dh,0ah,0 tfalttxt: db 0dh db ' Def.Cyl ' tfdcyl: db 0,0,0,0,0 db ' Head ' tfdhd: db 0,0,0 db ' Alt.Cyl ' tfacyl: db 0,0,0,0,0 db ' Head ' tfahd: db 0,0,0 db 0 ;terminator ;----------------------- sumerror: ld a,(dsense) and 7fh ;bit 6 mitpruefen ret z ;wegen SW Error ld a,(dsense) and 80h jr z,sumerr1 ld a,(dsense+1) ld c,a and 1fh ld de,sehead call madc ;Head Nr xor a ld h,a rl c rl h ;2~10 nach H rl c rl c rlca ;Lun nach A ld de,selun call madc ld a,(dsense+2) ld c,a and 3fh ld de,sesect call madc ;Sector Nr. rl c rl h rl c rl h ld a,(dsense+3) ld l,a ld de,secyl call mhldc ld hl,seerror call epstr ld e,'G'-'@' ld c,2 call bdos sumerr1: ld a,(dsense) ld b,a and 70h ;bit 6 einschliesslich SW Error ld hl,t0error sumerr2: jr z,sumerr3 call stext ;Text suchen sub a,10h jr sumerr2 sumerr3: call epstr ld hl,errormsgs ld a,(dsense) and 7fh ;incl. SW Error (bit 6) ld b,a sumerr4: call stext djnz sumerr4 call epstr scf ret stext: push af push bc xor a st1: cpi jr nz,st1 pop bc pop af ret seerror: db 0dh,0ah db ' Error on Lun ' selun: db 0,0,0 db ' Cylinder ' secyl: db 0,0,0,0,0 db ' Head ' sehead: db 0,0,0 db ' Sector ' sesect: db 0,0,0 db 0dh,0ah db 0 t0error: db 0dh,0ah,'Drive Error ',0dh,0ah,0 db 0dh,0ah,'Data Error ',0dh,0ah,0 db 0dh,0ah,'Command Error ',0dh,0ah,0 db 0dh,0ah,'Diagnostic Error ',0dh, 0ah,0 db 0dh,0ah,'Software Error ',0dh,0ah,0 errormsgs: db 0 ;No error db 'No Index',0dh,0ah,0 db 'No Seek, Command Complete',0dh,0ah,0 db 'Write/Drive Fault',0dh,0ah,0 db 'Drive not selected/Not Ready',0dh,0ah,0 db 0 db 'No Track or Cylinder Zero Found',0dh,0ah,0 db 'Multiple Drives Selected',0dh,0ah,0 db 'Seek/Command in Progress',0dh,0ah,0 db 'Cartridge Changed',0dh,0ah,0 db 0,0,0,0,0,0 db 'ID ECC Error',0dh,0ah,0 db 'Uncorrectable Data Error',0dh,0ah,0 db 'ID Address Mark Not Found',0dh,0ah,0 db 'Data Address Mark Not Found',0dh,0ah,0 db 'Record Not Found',0dh,0ah,0 db 'Seek Error',0dh,0ah,0 db 'Sequenzer/DMA Failure',0dh,0ah,0 db 'Write Protected',0dh,0ah,0 db 'Correctable ECC Error',0dh,0ah,0 db 'Bad Track Encountered',0dh,0ah,0 db 'Illegal Interleave Factor',0dh,0ah,0 db 0 db 'Illegal Access to an Alternate Track',0dh,0ah,0 db 'Alternate or Bad Track already Assigned',0dh,0ah,0 db 'No Alternate Track Found',0dh,0ah,0 db 'Illegal Alternate Track Address',0dh,0ah,0 db 'Invalid Command',0dh,0ah,0 db 'Illegal Disk Address',0dh,0ah,0 db 'Illegal Function for the current Drive Type',0dh,0ah,0 db 'Volume Overflow',0dh,0ah,0 db 0,0,0,0,0,0,0,0,0,0,0,0 db 'Data Buffer RAM Error',0dh,0ah,0 db 'EPROM Checksum/Internal Diagnostic Error',0dh,0ah,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 'Function shorted',0dh,0ah,0