long@sask.UUCP (Warren Long) (02/04/86)
I have been trying (unsuccessfully) to switch my disk drives to and fro from double density. It is easy to do from a DOS that does it. (eg. TOP DOS or MYDOS). What I want to do is to be able to do it from my program. I write everything in ACTION so assembly or machine code is quite acceptable. I will even translate it from BASIC string machine codes if I have to. Help!!!! Warren Long University of Saskatchewan Canada
langdon@lll-lcc.UUCP (02/07/86)
In article <328@sask.UUCP>, long@sask.UUCP (Warren Long) writes: > > I have been trying (unsuccessfully) to switch my disk drives > to and fro from double density. It is easy to do from a > DOS that does it. (eg. TOP DOS or MYDOS). > What I want to do is to be able to do it from my program. > I write everything in ACTION so assembly or machine code is > quite acceptable. Try this. It is supposed to become a directory fixer for DD diskettes; that is only part started, but density detection and switching are in there and they worked. ---------------------------------------------------------------------- Bruce Langdon L-472 langdon%lll-lcc@lll-crg.ARPA Physics Department "langdon#bruce%d"@lll-mfe.ARPA Lawrence Livermore National Laboratory Livermore, CA 94550 (415) 422-5444 UUCP: ..{gymble,ihnp4,seismo}!lll-crg!lll-lcc!langdon --------------------------------------------------------------------------- ; DISKFIX.AC1 12/23/85 A. B. Langdon DEFINE SIOUT="$80", SIOIN="$40" BYTE Dtimeout=[15] ; Device Control Block for SIO: BYTE DDEVIC=$0300, DUNIT=$0301, DCOMND=$0302, DSTATS=$0303, DTIMLO=$0306 CARD DBUF=$0304, DBYTE=$0308, DAUX12=$030A PROC SIOV=$E459() ;define location of serial bus handler BYTE FUNC DSio() ; finish set up of Device Control Block ; and call the serial I/O routine. DDEVIC = '1 DTIMLO = Dtimeout SIOV() RETURN (DSTATS) MODULE; SECTIO ---------------------- ; Adapted from OSS bbs. ; Sectors are numbered 1-720. BYTE FUNC SectIO(BYTE drive, CARD sector, buffer, BYTE density) DUNIT = drive DBUF = buffer ; Set byte count for this density IF (sector<=3) OR (density<3) THEN DBYTE = 128 ELSE DBYTE = 256 FI DAUX12 = sector RETURN (DSio()) BYTE FUNC ReadSector(BYTE drive, CARD sector, buffer, BYTE density) DCOMND = 'R DSTATS = SIOIN SectIO(drive, sector, buffer, density) [$60]; RETURN (SIO error code) BYTE FUNC WriteSector(BYTE drive, CARD sector, buffer, BYTE density) DCOMND = 'W DSTATS = SIOUT SectIO(drive, sector, buffer, density) [$60]; RETURN (SIO error code) MODULE; DENSITY --------------------- ; From Mark Reed, on ACS bulletin board. Mods by B. Langdon ;This program changes the density of a PERCOM-compatible drive from ;single to double density and vice versa. It also displays the values ;in the drive option table before and after the change. ;Note that by changing the Set_DENSITY() procedure you could configure ;the disk controller to handle a double sided or 96TPI (quad density) ;drive, assuming your controller can handle these drive types. ;(The PERCOM RFD-1 and ATR8000 can, the TRAK, INDUS, etc. can't) DEFINE RdOCmd="'N", WrOCmd="'O" BYTE ARRAY OptTable(12) BYTE Ntracks=OptTable, StepRate=OptTable+1, Nsides=OptTable+4, density=OptTable+5, present=OptTable+8 CARD Nsectors=OptTable+2, Nbytes=OptTable+6 PROC OPTION_TABLE_ERROR() PrintF("ERROR %D%E",DSTATS) RETURN PROC OPTION_TABLE(BYTE drive, CMND) DUNIT = drive DCOMND = CMND IF CMND=RdOCmd THEN ;read option table DSTATS = SIOIN ;set for data in ELSEIF CMND=WrOCmd THEN ;write option table DSTATS = SIOUT ;set for data out ELSE OPTION_TABLE_ERROR() RETURN FI DBYTE = 12 DBUF = OptTable DSio() IF DSTATS<>1 THEN OPTION_TABLE_ERROR() FI RETURN CARD FUNC SwapHiLo=*(CARD in) ; For Percom's 6809, must use Hi,Lo order. [$86 $A0] ; STX value low [$85 $A1] ; STA value high [$60] ; RETURN PROC TEST_OPTION_TABLE(BYTE drive) ; read the option table and displays the values BYTE ARRAY SR=[6 12 20 30] ; step rates CARD Ctemp OPTION_TABLE(drive, RdOCmd) IF DSTATS<>1 THEN RETURN FI Ctemp=SwapHiLo(Nsectors) PrintF("%D tracks of %D sectors, %D sides%E",Ntracks,Ctemp,Nsides+1) PrintF("step rate %D ms. 'present'=%D%E",SR(StepRate),present) Ctemp=SwapHiLo(Nbytes) PrintF("%D bytes/sector; 'density'=%D%E",Ctemp,density) RETURN PROC Set_DENSITY(BYTE drive, NEW_DENSITY) OPTION_TABLE(drive, RdOCmd) ;read option table IF NEW_DENSITY=1 THEN ;sets single density density=0 ;single/double flag Nbytes=SwapHiLo(128) OPTION_TABLE(drive, WrOCmd) ;write new info ELSEIF NEW_DENSITY=2 THEN ;sets double density density=4 ;density flag Nbytes=SwapHiLo(256) OPTION_TABLE(drive, WrOCmd) FI RETURN MODULE; ----------------------------- BYTE drive, j BYTE ARRAY buf(256), directory(1028) BYTE ARRAY VTOC(256), SMap(90)=VTOC+10 CARD TotSect=VTOC+1, NSUnused=VTOC+3 CARD sector, i CARD ARRAY SLinks(720) CARD POINTER link BYTE POINTER nfile ; Sectors are numbered 1-720 by drive. ; TotSec may always be 707. TYPE DirEntry=[BYTE flag CARD count, sect] ; flag: ; =$00 entry never used ; 01 now writing file ; 02 a version 2 file ; 20 entry protected ; 40 entry in use ; 80 entry was deleted ; count=number of sectors, ; start=number of 1st sector. DirEntry POINTER filedat BYTE FUNC TestVTOC(CARD sector, BYTE ARRAY map) ; FMS bug: there is no sector for bit 0, ; no bit for sector 720. BYTE index, mask mask = $80 RSH (sector&7) index = sector RSH 3 RETURN( map(index)&mask ) PROC SetVTOC(CARD sector, BYTE ARRAY map) BYTE index, mask mask = $80 RSH (sector&7) index = sector RSH 3 map(index) ==% mask ; also dec sectors avail*** RETURN CARD FUNC NextSect() BYTE FUNC TraceFile(BYTE filen, CARD sector, BYTE ARRAY map) ; follow file 'filen' starting at 'sector' ; setting VTOC as we go. CARD ns link = buf+Nbytes-3 nfile = link DO ReadSector(drive,sector,buf,density) SetVTOC(sector,map) nfile^ = ($FC&nfile^) RSH 2 PrintF("sec %U file %U%E",sector,nfile^) IF nfile^<>filen THEN RETURN(1) FI ns = SwapHiLo(link^) & $3FF SLinks(sector) = ns sector = ns UNTIL sector=0 OD RETURN(0) PROC TraceDisk() link = buf+Nbytes-3 nfile = link FOR sector=4 TO 719 DO ReadSector(drive,sector,buf,density) SLinks(sector) = SwapHiLo(link^) & $3FF PrintF("sec %U file %U%E",link^,nfile^) OD RETURN PROC GetDir() ; assemble all directory sectors Zero(directory, 1028) i = directory FOR sector=361 TO 368 DO ReadSector(drive, sector, buf, density) IF buf(0)=0 THEN EXIT FI ;no more after this MoveBlock(i, buf, 128) ;128 bytes used even in DD i ==+ 128 OD RETURN PROC PrintFN(BYTE POINTER name) BYTE DSPFLG=$2FE, i DSPFLG = 1 name ==+ 5 FOR i=1 TO 11 DO Put(name^) name ==+ 1 OD DSPFLG = 0 RETURN PROC ShowDir() BYTE nf CARD Nfree Nfree = 707 ;=720 -1 unused -3 boot -1 VTOC -8 directory i = 0 FOR nf=0 to 63 DO filedat = i+directory IF filedat.flag=0 THEN EXIT FI ;no more after this PrintFN(filedat) PrintF(" %U %H %U %U%E",nf,filedat.flag,filedat.count,filedat.sect) IF filedat.flag<$80 THEN Nfree ==- filedat.count FI i ==+ 16 OD PrintF("%U FREE SECTORS%E",Nfree) PrintF("VTOC: %U %U%E",TotSect,NSUnused) RETURN PROC MAIN() Print("ENTER THE DRIVE NUMBER: ") drive=InputB() TEST_OPTION_TABLE(drive) IF DSTATS<> 1 THEN RETURN FI NBytes = SwapHiLo(NBytes) ReadSector(drive,360,VTOC,density) Tracefile(0,4,SMap) RETURN GetDir() ShowDir() RETURN
DYOUNG@USC-ISID.ARPA (C. David Young) (02/10/86)
If I remember correctly, making a drive change densities to match the disk inserted is as easy as reading sector 1. Then you need only do a status call to find out what the density is. David Young -------
rb@mtuxn.UUCP (R.BOTWIN) (02/12/86)
[] David mentions reading sector 1 to switch densities, but I don't believe that is what was asked, or will in fact help. In fact, to insure compatible booting, the first three sectors are always 128 bytes, even if 18 X 256 DD formatting is used on the remainder of the disk. Most switchable drives use additional commands (M, N, O) to switch density according to a table passed in the call. These are documented by manufacturers using the system developed by PERCOM, and copied by AMDEK, ASTRA, TRAK, INDUS, etc. (even ATARI).... If you need the table layout, I can probably dig it up.... Rob Botwin, N2FC .....{utah-cs|seismo|decvax}!harpo!eagle!houxm!mtuxo!mtuxn!rb ATT/IS Labs (201) 577-5016 (Cornet 8-270-5016) FJ 1B-130