home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / UTILS / DIRUTL / ERADIR10.LBR / ERADIR.ZQ0 / ERADIR.Z80
Text File  |  2000-06-30  |  14KB  |  685 lines

  1. ; ERADIR.Z80  Vers 1.0  26Aug86
  2. ; (c) 1986 by W. Brimhall - Znode #52 (602)996-8739
  3. ; This program can be distributed free for non-commerical use.
  4.  
  5. ; ERADIR erases the directory of any CP/M 2.2 compatible disk by
  6. ; writing E5h to each byte of all sectors in the directory. This 
  7. ; program must be used with caution since any data that was on the 
  8. ; drive will be next to impossible to recover. One of the primary 
  9. ; uses for ERADIR is to initalize a RAM disk after power up.
  10.  
  11. ;Enter this command line to display the builtin help info:
  12. ;
  13. ;    ERADIR /
  14.  
  15. ;Enter this command line to Assemble & link:
  16. ;
  17. ;    ZAS ERADIR ; ZLINK ERADIR,SYSLIB/
  18.  
  19. ;Syslib routines:
  20.  
  21.     ext cin        ; input console to reg a
  22.     ext bist    ; bdos console input status
  23.     ext bout    ; bdos output reg a to console
  24.     ext bbline    ; bdos line input
  25.     ext crlf    ; output crlf to console
  26.     ext print    ; print inline message 
  27.     ext phldc    ; print hl in dec on con
  28.  
  29. bdos    equ 5
  30. cr    set 0dh
  31. lf    set 0ah
  32.  
  33. ; + + + +  ilprn  + + + +
  34.  
  35. ;This macro displays an inline string terminated with 0h 
  36. ;on the console without loosing control when tw tracing 
  37. ;with a debugger. It is used with the ilprn@ subroutine
  38. ;located at the end of the program.
  39.  
  40. ilprn    macro
  41.     call ilprn@    
  42.     ret
  43.     endm
  44.  
  45. ;-----------------------------
  46. ; COM file entry point @ 100h
  47. ;-----------------------------
  48.  
  49.     jp main        
  50.  
  51. ;--------------
  52. ; Help routine 
  53. ;--------------
  54.  
  55. help:    ilprn
  56.     db cr,lf
  57.     db 'ERADIR  Vers 1.0  26Aug86',cr,lf
  58.     db ' CP/M directory erase program.',cr,lf
  59.     db '  (c) 1986 by W.Brimhall Znode 52 (602) 996-8739',cr,lf
  60.     db '   (This program can be distributed free for '
  61.     db 'non-commerical use.)',cr,lf,lf
  62.     db '   ERADIR erases the directory of any '
  63.     db 'CP/M 2.2 compatible disk by',cr,lf
  64.     db '   writing E5h to each byte of all sectors '
  65.     db 'in the directory. This',cr,lf
  66.     db '   program must be used with caution since '
  67.     db 'any data that was on the',cr,lf
  68.     db '   drive will be next to impossible to recover. '
  69.     db 'ERADIR is especially',cr,lf
  70.     db '   suited for initalizing RAM disks '
  71.     db 'after power up.',cr,lf,lf
  72.     db '   Command Line Syntax:',cr,lf,lf
  73.     db '    ERADIR /    ;Display this help info.',cr,lf
  74.     db '    ERADIR d    ;Erase directory on drive "d" '
  75.     db '(A thru P).',cr,lf
  76.     db '    ERADIR        ;Prompt user for drive.',cr,lf,lf
  77.     db '    Information about the selected '
  78.     db 'drive is displayed and you are given',cr,lf
  79.     db '    a chance to abort before the actual '
  80.     db 'directory erase is performed.',cr,lf,lf,0
  81.     jp exit
  82.  
  83. ;------------------
  84. ; dbug entry point 
  85. ;------------------
  86.  
  87. dbug:    call main    ;ddt entry point
  88.     rst 38h        ;return to ddt
  89.  
  90. ;--------------
  91. ; main program 
  92. ;--------------
  93.  
  94. main:    ld (stack),sp    ;save ccp sp
  95.     ld sp,stack    ;set up new stack
  96.     ld c,0ch
  97.     call bdos    ;check cp/m version
  98.     ld a,l
  99.     cp 22h
  100.     jp nc,verok
  101.     ilprn
  102.     db cr,lf,'++Must have CP/M vers 2.2 or later...',0
  103.     jp abort
  104. verok:    call bjmps        ;set up local bios jumps
  105.  
  106.     ;Check for command line parameters.
  107.     
  108.     ld a,(80h)        ;a= command line length
  109.     or a
  110.     jr z,enter        ;prompt user if nul command line tail
  111.     ld a,(82h)
  112.     cp '/'
  113.     jp z,help        ;display help info if /
  114.     call valid        ;check for valid drive
  115.     jr nc,logdrv        ;jmp if A thru P
  116.  
  117.     ;Prompt user for drive.
  118.  
  119. enter:    ilprn
  120.     db cr,lf,'Logical drive (A: thru P:) ? ',0
  121.     or -1            ;select upper case input
  122.     call bbline        ;input line (syslib)
  123.     or a
  124.     jp z,abort        ;exit if cr only
  125.     call crlf
  126.     ld a,(hl)        ;a= selected logical drive
  127.     call valid        ;check for valid drive
  128.     jp c,error        ;jmp if bad 
  129.  
  130.     ;Log in the selected drive.
  131.  
  132. logdrv:    sub 'A'            ;convert to drive number
  133.     ld (drive),a        ;save drive number
  134.     call getsp        ;login & get trk & sec parms
  135.     jr nz,drvok        ;jmp if valid drive
  136. error:    ilprn
  137.     db '++Illegal drive name specified...',cr,lf,0
  138.     jp enter
  139.  
  140.     ;Display disk parameters and make double shure we want 
  141.     ;to continue...
  142.  
  143. drvok:    call dirgps    ;calculate number of directory groups
  144.     call stats    ;display drive statistics
  145.     ilprn
  146.     db cr,lf,lf,'OK to erase directory on drive ',0
  147.     ld a,(drive)
  148.     add a,'A'
  149.     call bout        ;display drive letter
  150.     ilprn
  151.     db ': (y/n, CR=n) ? ',0
  152.     or -1            ;select upper case input
  153.     call bbline        ;input line from console
  154.     or a
  155.     jp z,abort        ;abort if cr only
  156.     ld a,(hl)        ;get 1st char
  157.     cp 'Y'
  158.     jp nz,abort        ;abort if not Y            
  159.  
  160.     ;Now that a drive has been successfully selected & verified
  161.     ;we can go ahead and erase its directory.
  162.  
  163.     ilprn
  164.     db cr,lf,lf,'Erasing directory',lf,0
  165.     call filbfr    ;fill default dma buffer with e5h
  166.     call group0    ;set track & sector for group 0
  167. nxtrec:    ld bc,dskbfr    ;bc--> disk write buffer
  168.     call lsdma    ;set dma address
  169.     ilprn
  170.     db cr,'Track ',0
  171.     ld hl,(curtrk)
  172.     call phldc
  173.     ilprn
  174.     db ' Sector ',0
  175.     ld hl,(physec)
  176.     call phldc
  177.     call wrtsec    ;write 1 sector
  178.     call nxtsec    ;advance to next sector within group
  179.     jr nc,nxtrec    ;loop til end of group
  180.     ld hl,group
  181.     inc (hl)    ;group=group+1
  182.     ld a,(dgrps)    ;a=number of dir groups
  183.     cp (hl)
  184.     jp nz,nxtrec    ;loop til end of directory
  185.     call crlf    ;output crlf to console (syslib)
  186.     ld hl,(count)
  187.     ld a,h
  188.     or l
  189.     jr z,dirok    ;jmp if no write errors
  190.     call phldc    ;display error count
  191.     ilprn
  192.     db ' Media errors in directory, Reformat and try again...'
  193.     jr exit        ;exit
  194. dirok:    ilprn
  195.     db cr,lf,'Successful Directory erase',cr,lf,0
  196.     jr exit
  197.     
  198. ; + + + +  abort & exit  + + + +
  199.  
  200. ;Exit back to the CCP.
  201.  
  202. abort:    ilprn
  203.     db cr,lf,'++ERADIR aborted...',cr,lf,0
  204. exit:    ld bc,80h    ;bc--> default dma buffer
  205.     call lsdma    ;restore dma address to default buffer
  206.     ld a,(4)    ;get current drive
  207.     ld c,a        ;c= drive
  208.     ld e,1        ;reset "new select" flag
  209.     call lseldk    ;restore original drive selection
  210.     ld sp,(stack)    ;restore CCP sp
  211.     ret
  212.  
  213. ; + + +  valid  + + +
  214.  
  215. ;Return cf reset if reg A contains a drive name from 'a' to 'p'
  216.  
  217. valid:    and 5fh        ;convert drive to upper case
  218.     cp 'A'
  219.     ret c        ;cf=set if drive < 'a'
  220.     cp 'P'+1
  221.     ccf
  222.     ret        ;cf=set if drive > 'p'
  223.     
  224. ; + + +  getsp  + + +
  225.     
  226. ;Get track and sector parameters for drive.
  227. ;Return zf set if drive is not in system.
  228.  
  229. getsp:    ld a,(drive)
  230.     ld c,a        ;c=current drive
  231.     ld e,0        ;set "new select" flag
  232.     call lseldk    ;select disk through bios to get dph
  233.     ld a,h
  234.     or l
  235.     ret z        ;ret if select error
  236.     ld e,(hl)    ;get the sector table pntr
  237.     inc hl
  238.     ld d,(hl)
  239.     inc hl
  240.     ex de,hl
  241.     ld (sectbl),hl
  242.     ld hl,8        ;offset to dpbptr
  243.     add hl,de
  244.     ld a,(hl)
  245.     inc hl
  246.     ld h,(hl)
  247.     ld l,a        ;hl --> dpb start (source)
  248.     ld de,dpb    ;de --> local area for dpb (dest)
  249.     ld bc,14    ;bc= bytes to move
  250.  
  251.     ;fill in disk params
  252.  
  253.     ldir        ;move dpb into local area
  254.     ld hl,grpdsp
  255.     ld a,(blm)    ;blm=sectors per group
  256.     ld (hl),a    ;grpdsp=max
  257.     ld hl,(dsm)    ;dsm=total groups
  258.     ld (group),hl    ;group=max
  259.     call gtksec    ;compute last track & sector on drive
  260.     ld hl,(cursec)
  261.     ld (maxsec),hl
  262.     ld hl,(curtrk)
  263.     ld (maxtrk),hl
  264.     or -1
  265.     ret        ;a= -1, zf=reset
  266.  
  267. ; + + +  filbfr  + + +
  268.  
  269. ;Fill dskbfr with E5h.
  270.  
  271. filbfr:    ld hl,dskbfr    ;hl--> dma buffer
  272.     ld c,80h    ;c= 80h= byte count
  273. filbf1:    ld (hl),0e5h    ;load a byte
  274.     inc hl
  275.     dec c
  276.     jr nz,filbf1    ;loop til c=0
  277.     ret
  278.     
  279. ; + + +  group0  + + +
  280.  
  281. ;Set track & sector for group 0.
  282.  
  283. group0:    ld hl,0
  284.     ld (group),hl    ;group=0
  285.     ld a,0
  286.     ld (grpdsp),a    ;displacement=0
  287.     call gtksec    ;set track & sector
  288.     ret
  289.  
  290. ; + + +  dirgps  + + +
  291.  
  292. ;Calculate the number of directory groups
  293. ;and store at dgrps.
  294.  
  295. dirgps:    ld hl,(al0)    ;hl=dir group allocation bits
  296.     ld c,16    ;c=loop count
  297.     ld b,0        ;b=group count
  298. dirg1:    call rotrhl
  299.     jp nc,notset    ;jmp if bit is not set
  300.     inc b
  301. notset:    dec c
  302.     jp nz,dirg1
  303.     ld a,b
  304.     ld (dgrps),a    ;store directory groups
  305.     ret
  306.  
  307. ; + + +  stats  + + +
  308.  
  309. ;Print disk statistics
  310.  
  311. stats:    ilprn
  312.     db cr,lf,'Disk information for drive ',0
  313.     ld a,(drive)
  314.     add 'A'
  315.     call bout
  316.     ilprn
  317.     db ':',cr,lf,' tracks:',9,0
  318.     ld hl,(maxtrk)
  319.     inc hl
  320.     call phldc
  321.     ilprn
  322.     db cr,lf,' sys tracks:',9,0
  323.     ld hl,(systrk)
  324.     call phldc
  325.     ilprn
  326.     db cr,lf,' recs/trk:',9,0
  327.     ld hl,(spt)
  328.     call phldc
  329.     ilprn
  330.     db cr,lf,' recs/group:',9,0
  331.     ld a,(blm)
  332.     inc a
  333.     ld l,a
  334.     ld h,0
  335.     call phldc
  336.     ilprn
  337.     db cr,lf,' tot grps:',9,0
  338.     ld hl,(dsm)
  339.     call phldc
  340.     ilprn
  341.     db cr,lf,' dir entries:',9,0
  342.     ld hl,(drm)
  343.     inc hl
  344.     call phldc
  345.     ilprn
  346.     db cr,lf,' dir groups:',9,0
  347.     ld hl,(dgrps)
  348.     ld h,0
  349.     call phldc
  350.     ret
  351.  
  352. ; + + +  report  + + +
  353.  
  354. ;Report error information on consol
  355.  
  356. report:    ilprn
  357.     db cr,lf,'media error : track ',0
  358.     ld hl,(curtrk)
  359.     call phldc
  360.     ilprn
  361.     db ' physical sector ',0
  362.     ld hl,(physec)
  363.     call phldc
  364.     call crlf
  365.     ret
  366.  
  367. ; + + +  nxtsec  + + +
  368.  
  369. ;advance to next sector.
  370. ;ret cf set when next group is reached
  371.  
  372. nxtsec:    ld a,(grpdsp)    ;a=sector within group
  373.     inc a
  374.     ld (grpdsp),a    ;bump to next sector
  375.     ld d,a        ;save in d
  376.     ld a,(blm)    ;a=sectors per group
  377.     cp d
  378.     ret nc        ;ret cf=0 if same group
  379.     xor a
  380.     ld (grpdsp),a    ;else make displacement=0
  381.     scf
  382.     ret        ;ret cf set
  383.  
  384. ; + + +  settrk  + + +
  385.  
  386. ;Set track # to value stored at curtrk.
  387.  
  388. settrk:    ld hl,(curtrk)
  389.     ld b,h
  390.     ld c,l
  391.     call lstrk    ;local bios set track call
  392.     ret
  393.  
  394. ; + + +  setsec  + + +
  395.  
  396. ;Set the physical sector number through bios by taking the
  397. ;logical sector value stored at cursec and using the sector
  398. ;translation table to convert it to its physical value.
  399.  
  400. setsec:    push hl
  401.     ld hl,(cursec)
  402.     ex de,hl
  403.     push de
  404.     ld hl,(systrk)
  405.     ex de,hl
  406.     ld hl,(curtrk)
  407.     call subde
  408.     pop bc
  409.     ld h,b
  410.     ld l,c
  411.     jp nc,notsys
  412.     ld a,(first0)    ;see if first sec 0
  413.     or a
  414.     jp nz,sets1    ;no, jump away
  415.     dec hl        ;yes, so decrement
  416.     jp sets1    ;requested, then go
  417.  
  418. notsys:    ld hl,(sectbl)
  419.     ex de,hl
  420.     dec bc
  421.     call lsectn
  422.     ld a,(spt+1)    ;if spt<256 (hi-ord = 0)
  423.     or a        ;then force 8-bit translation
  424.     jp nz,sets1    ;else keep all 16 bits
  425.     ld h,a
  426.  
  427. sets1:    ld (physec),hl
  428.     ld b,h
  429.     ld c,l
  430.     call lssec
  431.     pop hl
  432.     ret
  433.  
  434. ; + + +  gtksec  + + +
  435.  
  436. ;Convert group & displacement to track & sector.
  437.  
  438. gtksec:    ld hl,(group)    ;hl = group #
  439.     ld a,(bsh)
  440. gloop:    add hl,hl
  441.     dec a
  442.     jp nz,gloop
  443.     ld a,(grpdsp)
  444.     add a,l        ;can't carry
  445.     ld l,a
  446.  
  447.     ;Divide by # of sectors, quotient=track, remainder=sector
  448.  
  449.     ex    de,hl
  450.     ld hl,(spt)
  451.     call neg
  452.     ex    de,hl
  453.     ld bc,0
  454.  
  455. divlp:    inc bc
  456.     add hl,de
  457.     jp c,divlp
  458.     dec bc
  459.     ex    de,hl
  460.     ld hl,(spt)
  461.     add hl,de
  462.     push hl
  463.     ld hl,(systrk)
  464.     add hl,bc
  465.     ld (curtrk),hl
  466.     pop hl
  467.     inc hl
  468.     ld (cursec),hl
  469.     ret
  470.  
  471. ; + + +  wrtsec  + + +
  472.  
  473. ;Write sector to disk.
  474.  
  475. wrtsec:    xor a
  476.     call gtksec    ;convert group to track & sector
  477.     call setsec    ;set sector
  478.     call settrk    ;set track
  479.     call lwrite    ;local bios disk write
  480.     or a
  481.     ret z        ;ret if good write
  482.     ld hl,(count)
  483.     inc hl
  484.     ld (count),hl    ;inc error count
  485. rdsec1:    call report    ;report error on consol
  486.     ret
  487.  
  488. ; + + +  prndrv  + + +
  489.  
  490. ;print current drive name on consol
  491.  
  492. prndrv:    ld a,(drive)    ;get current drive number
  493.     add 'a'        ;convert to ascii name
  494.     call bout
  495.     ld a,':'
  496.     call bout
  497.     ret
  498.  
  499. ; + + +  bjmps  + + +
  500.  
  501. ;This subroutine sets up local jumps to the bios
  502.  
  503. bjmps:    ld hl,(1)
  504.     ld de,3
  505.     add hl,de
  506.     ld (lconst+1),hl
  507.     add hl,de
  508.     ld (lconin+1),hl
  509.     add hl,de
  510.     ld (lbout+1),hl
  511.     add hl,de
  512.     ld (llist+1),hl
  513.     add hl,de        ;punch
  514.     add hl,de        ;reader
  515.     add hl,de
  516.     ld (lhome+1),hl
  517.     add hl,de
  518.     ld (lseldk+1),hl
  519.     add hl,de
  520.     ld (lstrk+1),hl
  521.     add hl,de
  522.     ld (lssec+1),hl
  523.     add hl,de
  524.     ld (lsdma+1),hl
  525.     add hl,de
  526.     ld (lread+1),hl
  527.     add hl,de
  528.     ld (lwrite+1),hl
  529.     add hl,de
  530.     add hl,de
  531.     ld (lsectn+1),hl
  532.     ret
  533.  
  534. lconst:    jp $-$        ;filled in by bjmps routine
  535. lconin:    jp $-$
  536. lbout:    jp $-$
  537. llist:    jp $-$
  538. lhome:    jp $-$
  539. lseldk:    jp $-$
  540. lstrk:    jp $-$
  541. lssec:    jp $-$
  542. lsdma:    jp $-$
  543. lread:    jp $-$
  544. lwrite:    jp $-$
  545. lsectn:    jp $-$
  546.  
  547. ; + + +  neg  + + +
  548.  
  549. ;2's complement hl ==> hl
  550.  
  551. neg:    ld a,l
  552.     cpl
  553.     ld l,a
  554.     ld a,h
  555.     cpl
  556.     ld h,a
  557.     inc hl
  558.     ret
  559.  
  560. ; + + +  rotrhl  + + +
  561.  
  562. ;hl/2 ==> hl
  563.  
  564. rotrhl:    or a
  565.     ld a,h
  566.     rra
  567.     ld h,a
  568.     ld a,l
  569.     rra
  570.     ld l,a
  571.     ret
  572.  
  573. ; + + +  subde  + + +
  574.  
  575. ;hl-de ==> hl
  576.  
  577. subde:    ld a,l
  578.     sub e
  579.     ld l,a
  580.     ld a,h
  581.     sbc a,d
  582.     ld h,a
  583.     ret
  584.  
  585. ; + + +  mult  + + +
  586.  
  587. ;quick kludge multiply
  588. ;hl=de ==> hl
  589.  
  590. mult:    push bc
  591.     push de
  592.     ex    de,hl
  593.     ld b,d
  594.     ld c,e
  595.     ld a,b
  596.     or c
  597.     jp nz,mulcon
  598.     ld hl,0        ;filter special case
  599.     jp mldone    ;    of multiply by 0
  600.  
  601. mulcon:    dec bc
  602.     ld d,h
  603.     ld e,l
  604.  
  605. multlp: ld a,b
  606.     or c
  607.     jp z,mldone
  608.     add hl,de
  609.     dec bc
  610.     jp multlp
  611.  
  612. mldone:    pop de
  613.     pop bc
  614.     ret
  615.  
  616. ; * * * *  ilprn@  * * * *
  617.  
  618. ;Special inline string print subroutine that will
  619. ;not lose control when tw tracing with Zsid. this
  620. ;routine returns to the instruction following the
  621. ;ilprn@ which must be a ret. Zsid places a
  622. ;break point at that address. the address of the
  623. ;instruction following the inline string is calculated
  624. ;and returned on the stack.
  625.  
  626. ;destroys:    a,d,e & flags
  627.  
  628. ilprn@:    ld (hlsave),hl    ;save hl
  629.     pop hl        ;hl= return address
  630.     push hl        ;put back on stack
  631.     inc hl        ;hl --> inline string
  632. ilp1:    ld a,(hl)
  633.     or a
  634.     jr z,ilp2    ;jmp if end of string
  635.     call bout
  636.     inc hl
  637.     jp ilp1
  638. ilp2:    inc hl        ;hl= next instruction address
  639.     ex (sp),hl    ;(sp)= next instruction address,
  640.             ;hl= return address
  641.     push hl        ;(sp)= return address
  642.     ld hl,(hlsave)    ;restore hl
  643.     ret        ;return to "ret" instruction
  644.             ;following "ilprn@"
  645.  
  646. ; * * *  data area  * * *
  647.  
  648. hlsave:    ds 2    ;temp storage for hl
  649. drive:    ds 1    ;current drive
  650. dgrps:    ds 1    ;directory groups
  651. dmaptr:    ds 2    ;dma buffer pointer
  652. group    dw 0    ;current cp/m group number
  653. grpdsp    db 0    ;sector displacement within group
  654. count    dw 0    ;write error counter
  655. saveflg    db 0
  656. curtrk    dw 0
  657. cursec    dw 1
  658. physec    dw 1
  659. filect    dw 0
  660. qflag    db 0    ;quiet? (0=no)
  661. first0    db 0    ;sets to 0 if first sec # is 0
  662. maxtrk    dw 0
  663. maxsec    dw 0
  664. ver2fl    db 0
  665. sectbl    dw 0    ;pointer to sector skew table
  666.  
  667. ;The disk parameter block is moved here from cp/m
  668.  
  669. dpb:    equ $    ;disk parameter block (copy)
  670. spt:    ds 2    ;sectors per track
  671. bsh:    ds 1
  672. blm:    ds 1    ;group size -1
  673. exm:    ds 1
  674. dsm:    ds 2    ;total groups
  675. drm:    ds 2    ;directory entries -1
  676. al0:    ds 1    ;dir group allocation bits
  677. al1:    ds 1
  678. cks:    ds 2
  679. systrk:    ds 2    ;system tracks
  680. dskbfr:    ds 128    ;disk sector write buffer
  681.     ds 128
  682. stack:    ds 2
  683.  
  684.     end
  685.