🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: net.micro.atari
Article #2408

Re: Single to double density switching

#2408
From: langdon
Date: Fri, 07 Feb 1986 17:10
268 lines
8163 bytes
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
Technical Details
Message-ID: <140@lll-lcc.UUcp>
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxn!ihnp4!houxm!whuxl!whuxlm!akgua!gatech!ut-sally!topaz!lll-crg!lll-lcc!langdon
References: <328@sask.UUCP>

Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxn!ihnp4!houxm!whuxl!whuxlm!akgua!gatech!ut-sally!topaz!lll-crg!lll-lcc!langdon
From: langdon@lll-lcc.UUCP
Newsgroups: net.micro.atari
Subject: Re: Single to double density switching
Message-ID: <140@lll-lcc.UUcp>
Date: Fri, 7-Feb-86 12:10:23 EST
Article-I.D.: lll-lcc.140
Posted: Fri Feb  7 12:10:23 1986
Date-Received: Sun, 9-Feb-86 08:23:40 EST
References: <328@sask.UUCP>
Distribution: net
Organization: Lawrence Livermore Labs, LCC, Livermore Ca
Lines: 268
Summary: Action program to switch disk drive density and etc.